简体   繁体   中英

Polymorphic functions in Record Types Haskell

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM