Question

Comment se fait-il, que les contrôles de type suivants

{-# 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}

mais lors de la modification de la signature du type de setFunFoo à

setFunFoo :: ((Foo a) => a -> IO ()) -> Bar -> Bar

il ne fonctionne pas? Y at-il un moyen d'exprimer le code ci-dessus sans l'FunFoo synonyme de type?

Était-ce utile?

La solution

Vous devez ajouter un forall explicite comme ceci:

setFunFoo :: (forall a. (Foo a) => a -> IO ()) -> Bar -> Bar

La raison est parce que vous voulez que la portée de la a variable de type à être limité au type du premier argument à setFunFoo. Sans l'forall explicite, le type Dessucré est la suivante:

setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top