In einer typisierten Umgebung muss man vorsichtig sein. Ihre Lambda-Terme funktionieren in einer untypisierten Einstellung gut, benötigen aber einige Verbesserungen in einer getippten Einstellung.
Wir müssen einen Typ für Church Booleans definieren. Wählen wir den folgenden parametrischen monomorphen Typ.
type B a = a -> a -> a
Dann lassen Sie uns Typ Anmerkungen hinzufügen zu überprüfen, was falsch ist:
true :: B a
true = \t f -> t
false :: B a
false = \t f -> f
toBool :: B Bool -> Bool
toBool = \b -> b True False
So weit, so gut. Jedoch:
bnot :: B a -> B a
bnot = \b -> b false true
ergibt einen Typfehler, da z.B. false
hat Typ B a
, nicht a
, so ist die Anwendung b false
schlecht typisiert. Wir können dies umgehen, indem wir ein paar a
Argumente x y
hinzufügen und die Funktion entsprechend vereinfachen.
bnot = \b x y -> b (false x y) (true x y)
-- or, more simply:
bnot = \b x y -> b y x
-- or even
bnot = flip
Dieser Typ wird überprüft. In ähnlicher Weise können wir bxor
überarbeiten, um es Prüfung zu machen Typ:
bxor :: B a -> B a -> B a
bxor = \b1 b2 x y -> b1 (bnot b2 x y) (b2 x y)
Alternativ mit der imprädikative Kirche Codierung von booleans können wir Ihren ursprünglichen Code eingeben machen überprüfen, wie es ist, mit Ausnahme der Zugabe von die relevanten Signaturen. Dies erfordert höherrangige Typen.
{-# LANGUAGE Rank2Types #-}
type BI = forall a. a -> a -> a
trueI :: BI
trueI = true
falseI :: BI
falseI = false
toBoolI :: BI -> Bool
toBoolI = \b -> b True False
bnotI :: BI -> BI
bnotI = \b -> b falseI trueI
bxorI :: BI -> BI -> BI
bxorI = \b x -> b (bnotI x) x
Ich glaube 'bnot' sollte sein' \ b -> b falsch wahr '. –
Welchen Fehler bekommen Sie? Ich bekomme keins. –
Ich denke, das Problem ist, dass 'bnot' einen komplizierten Typ' ((t -> t1 -> t1) -> (t3 -> t4 -> t3) -> t2) -> t2 'hat, was den Typ von' bxor' noch schlimmer. Diese Frage sollte klären, was das eigentliche Problem ist. Vergleichen Sie es zum Beispiel mit "bnot = \ b x y -> b y x". – chi