Haskell A reference to a type variable

I sometimes came across this problem and finally wanted to ask if a common solution or template exists. Is it possible to make a type variable in a nested context a type reference from an external context? For instance,

foo :: a -> ... -> .. foo = ... where bar :: a -> ... 

Now bar a is different from foo a . Usually this is what I want, but sometimes it makes my life difficult, and I need to make them the same. I used dirty tricks to get the type checker to combine the two in the past, but sometimes they interrupt. Here is my last example (Parsec function) that prompted me to finally ask this question.

 data Project = ... deriving Enum data Stuff = ... pProject :: Monad m => P m Stuff pProject = do stuff <- pStuff ... convert stuff <$> pEnum :: P m Project pEnum :: (Monad m, Enum a) => String -> P ma pEnum = ... 

The convert function needs a type, so I needed to specify the annotation :: P m Project . However, this means that I must also enter m , which, unfortunately, is not the same m as in the function signature. The type controller reports this with:

Failed to infer Monad m1 associated with using pEnum from Monad m context

Is there any way to refer to the signature of the function m without any ugly hack? (An ugly hack will insert dummy code that is not executed, but exists only to combine the two types.)

+6
source share
1 answer

You are looking for the ScopedTypeVariables extension, which allows you to reference type variables from contained areas.

 {-# LANGUAGE ScopedTypeVariables #-} 

For backward compatibility, this applies only to signature types with explicit forall . Therefore you need to write:

 pProject :: forall m. Monad m => P m Stuff 

You can then reference the correct variable of type m inside the pProject .

+13
source

Source: https://habr.com/ru/post/979205/


All Articles