Why can't a function use a type limited to a type class only?

I do not have enough vocabulary to formulate this question (and therefore to search for answers, so I apologize if the answer is easily available). Consider the following

class RunFoo m where
  runFoo :: m a -> a

class RunFooWrapper m where
  doRunFoo :: (RunFoo n) => n a -> m a

newtype RunFast a = RunFast a

newtype RunSlow a = RunSlow a

fooExample :: (RunFoo m) => m Bool
fooExample = undefined

fooWrapperExample :: (RunFooWrapper m) => m Bool
fooWrapperExample = doRunFoo fooExample

It will not compile: Could not deduce (RunFoo n0) arising from a use of ‘doRunFoo’.

It seems that the compiler (GHC 7.10) insists on a specific instance mof fooExampleand therefore refuses to continue. But in this case, I don’t see why the program is not typed - it fooExampleexplicitly defines a RunFoo m, but everything doRunFoorequires it RunFoo x. So why is this not working?

- (, - ), ? , doRunFoo - (?) RunFoo m => m ( , - RunFoo).

, , - , !

, , , , , . , , . , , . , , ,

class (RunFoo (RunFooM m)) => RunFooWrapper m where
  type RunFooM m :: * -> *
  doRunFoo :: RunFooM m a -> m a

instance RunFooWrapper RunFooWrapperSlow where 
  type RunFooM RunFooWrapperSlow = RunSlow
  doRunFoo :: [...]

, fooExample m - , , , , haoformayor.

+4
1

RankNTypes

{-# language RankNTypes #-}    

class RunFoo m where
  runFoo :: m a -> a

class RunFooWrapper m where
  doRunFoo :: (forall n. RunFoo n => n a) -> m a

fooExample :: RunFoo m => m Bool
fooExample = undefined

fooWrapperExample :: RunFooWrapper m => m Bool
fooWrapperExample = doRunFoo fooExample

(forall n. RunFoo n => n a) -> m a - . fooExample, forall m. RunFoo m => m Bool (forall ), m n, . , , . RunFoo, , n, , .

, forall n. RunFoo n => n a -> m a. , n, RunFoo n, n a . ( n) .

, , . . RankNTypes, , . .

+10

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


All Articles