Your code will not work because Haskell does not reuse or scope type variables; a in wrap :: (Read a, Show b) => (a -> b) -> (String -> String) is completely different from what is in read s :: a (and they are both universally quantitative) . This is source a1 in the error message; GHC is an alpha conversion program to
wrap :: (Read a, Show b) => (a -> b) -> (String -> String) wrap f = \s -> show $ f (read s :: a1)
However, the type of the argument f fixed inside wrap , so just deleting the type annotation works fine. Your function will become
wrap :: (Read a, Show b) => (a -> b) -> (String -> String) wrap f = \s -> show $ f (read s)
And you can use it:
ghci> map ($ "42") [wrap (+ (7 :: Integer)), wrap (* (2.0 :: Double))] ["49","84.0"]
Note that this means that read s has a type that you cannot write. In Haskell 2010 (or 98), the only way around this is to use a function like asTypeOf :: a -> a -> a ; asTypeOf is just const , but thanks to its type signature, it limits its first, returned argument to the same type as its second. Then, of course, you have to call such a variable of type a . To do this, the following will work:
wrap :: (Read a, Show b) => (a -> b) -> (String -> String) wrap f = \s -> show $ f (read s `asTypeOf` fInput) where fInput = undefined fOutput = f fInput
In GHC, to avoid this, you can enable the ScopedTypeVariables extension ; with this, if you explicitly qualify all your type variables with forall , they will be messed up just like value level names. Then your code will become
{-
But remember that for this simple example, you don't need type annotations at all.
Antal spector-zabusky
source share