How does it come, that the following type checks
{-# LANGUAGE RankNTypes #-}
module Main where
class Foo a where
type FunFoo = (Foo a) => a -> IO ()
data Bar = Bar {
funFoo :: FunFoo
}
setFunFoo :: FunFoo -> Bar -> Bar
setFunFoo action bar = bar {funFoo = action}
but when changing the type signature off setFunFoo to
setFunFoo :: ((Foo a) => a -> IO ()) -> Bar -> Bar
it does not? Is there a way to express the above code without the type synonym FunFoo?
Some common synonyms of type are character, description, kind, nature, and sort.
vocation. walk. line of business. métier. nine-to-five.
A synonym is a word, morpheme, or phrase that means exactly or nearly the same as another word, morpheme, or phrase in a given language. For example, in the English language, the words begin, start, commence, and initiate are all synonyms of one another: they are synonymous.
You need to add an explicit forall
like so:
setFunFoo :: (forall a. (Foo a) => a -> IO ()) -> Bar -> Bar
The reason for this is because you want the scope of the type variable a
to be limited to the type of the first argument to setFunFoo
. Without the explicit forall
, the desugared type is this:
setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With