i've stumbled upon a behaviour I can't explain in Haskell. I'm trying to store a polymorphic function in a Record Type, which I want to use in a ReaderT Monad. When I get my function with asks
, the compiler doesn't recognize it as polymorphic and seems to fix the type on the first occurance of the function. I created a minimal example of this in ghci:
{-# LANGUAGE Rank2Types #-}
data Test = Test {f :: (forall a. a -> a)}
runReaderT (asks f
>>= \f -> (liftIO . putStrLn $ show (f 2 :: Int))
>> (liftIO . putStrLn $ show (f "hello"))
) (Test id)
When trying to run this, I get:
Couldn't match expected type ‘Int’ with actual type ‘[Char]’
In the first argument of ‘f’, namely ‘"hello"’
In the first argument of ‘show’, namely ‘(f "hello")’
In the second argument of ‘($)’, namely ‘show (f "hello")’
However, following code works:
runReaderT (ask
>>= \(Test f) -> (liftIO . putStrLn $ show (f 2 :: Int))
>> (liftIO . putStrLn $ show (f "hello"))
) (Test id)
So is it something special with asks
? I'm grateful for any advice on this.
Last time I checked, GHC could not infer higher rank types. Thus, when you have
\f -> ... f x .... f y
the f
can never be polymorphic.
There are only two places where the type of some variable is so obvious that type inference recognizes the higher rank type: in patterns that declare higher rank fields and in the LHS of annotated functions.
It also should work to give the type explicitly, like in
\(f :: forall a.a -> a) -> .... f x ... f y
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.