Frage

Wie kommt es, dass die folgenden Typprüfungen

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

aber bei Änderung der Art Signatur aus setFunFoo zu

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

nicht? Gibt es einen Weg, um den obigen Code, ohne die Art Synonym FunFoo auszudrücken?

War es hilfreich?

Lösung

Sie müssen eine explizite forall hinzufügen wie folgt:

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

Der Grund dafür ist, dass Sie den Umfang des Typs Variable a wollen auf den Typ des ersten Arguments zu setFunFoo beschränkt. Ohne ausdrücklichen forall, der entzuckert Typ ist dies:

setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top