I haven’t been able to figure this out. I see if I remove mod
which requires Integral
as I did in getFnA
it works.
In other languages I know I would do if (typeof x) == Integral else ...
kind of thing my understanding is you can do a runtime type check in Haskell
The error gives a suggestion “Probable fix: use a type annotation to specify what ‘a0’ should be.” but I have not been able to figure out how to do that.
getFn :: (Foldable t, Fractional a, Integral a) => t Char -> Either String (a -> a -> a, String)
getFn str
| '+' `elem` str = Right ((+), "+")
| '-' `elem` str = Right ((-), "-")
| '*' `elem` str = Right ((*), "*")
| '/' `elem` str = Right ((/), "/")
| '%' `elem` str = Right (mod, "%")
| otherwise = Left "Invalid operator. Must be one of +, -, *, /, %"
getFnA :: (Foldable t, Fractional a) => t Char -> Either String (a -> a -> a, String)
getFnA str
| '+' `elem` str = Right ((+), "+")
| '-' `elem` str = Right ((-), "-")
| '*' `elem` str = Right ((*), "*")
| '/' `elem` str = Right ((/), "/")
| otherwise = Left "Invalid operator. Must be one of +, -, *, /, %"
simpleCalc :: IO ()
simpleCalc = do
userInput <- getContents -- expected: "1+2"
let a = getFn userInput -- Error appears here
...
Here is the error
• Ambiguous type variable ‘a0’ arising from a use of ‘getFn’
prevents the constraint ‘(Fractional a0)’ from being solved.
Relevant bindings include
a :: (a0 → a0 → a0, String)
(bound at /home/klequis/projects/simpleCalc/src/Lib.hs:36:7)
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Fractional Double – Defined in ‘GHC.Float’
instance Fractional Float – Defined in ‘GHC.Float’
…plus 9 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: getFn userInput
In an equation for ‘a’: a = getFn userInput
In the expression:
do userInput ← getContents
let a = getFn userInput
print "hi"typecheck(-Wdeferred-type-errors)