2016-03-22 7 views
1

Erstes Posting auf diesem Tag und ich unternehme immer noch vorläufige Schritte mit der Sprache, aber ich habe einige dynamische FP Hintergrund, so dass ich schon ein paar Konzepte vertraut bin.Komposition mit zweideutigen Typen

Ich habe eine isZero Funktion definiert.

isZero :: Int -> Bool 
isZero x = x == 0 

Und ich versuche es mit der eine isMultiple Funktion erstellen mod Funktion zu komponieren.

isMultiple = isZero . mod 

Dies resultiert jedoch in einer Typübereinstimmung, da es die Signatur des erwartet a0 -> Int und mod sein a0 -> a0 -> a0 ist (vorausgesetzt, dies ist, da sie mehrere Genauigkeiten unterstützt).

Ich habe festgestellt, dass, wenn ich sie nur explizit komponieren (und eine Typ-Signatur zur Verfügung stellen), dann gibt es keine Probleme.

isMultiple :: Int -> Int -> Bool 
isMultiple x n = isZero $ mod x n 

Gibt es eine Möglichkeit compose Funktionen mit mehrdeutigen Typen zu verwenden, um den . Operator?

+2

'\ x -> isZero. mod x = \ x -> (.) istZero (mod x) = (.) isZero. mod' – user2407038

Antwort

6

Nun, schauen wir uns die Typen in Ihrem ersten Definition isMultiple einen Blick:

(.)   :: (b -> c ) -> (a -> b   ) -> a -> c 
isZero   :: Int -> Bool 
mod   ::     Int -> Int -> Int 
        -- same as  Int -> (Int -> Int) 

Wie Sie sehen können, beide b ‚s sind nicht die gleichen. Deshalb funktioniert es nicht. Man kann jedoch erhalten, damit es funktioniert, aber das ist nicht so einfach für das Auge mehr:

isMultiple = (isZero.) . mod 
      = ((.) isZero) . mod 
      = \x -> ((.) isZero) . mod $ x 
      = \x -> ((.) isZero) (mod x) 
      = \x -> (.) isZero (mod x) 
      = \x -> isZero . mod x 

Wie Sie sehen können, mod x hat Int -> Int geben, und eignet sich daher für Komposition mit (.) und isZero.

+0

Ok, also ist die Diskrepanz die LHS 'b' erwartet ein' Int' aber ein '(Int -> Int) 'bekommen? Das Problem besteht also darin, eine Funktion zu schreiben, die> = zwei Argumente erwartet? –

+2

@DanPrince: Grundsätzlich, ja (in diesem Fall; 'map. Mod' hat dieses Problem nicht zum Beispiel, aber das hat andere Semantik). Aber es ist möglich, dies mit einer anderen Anwendung von '(.)' Zu umgehen. Es gibt ein [tool] (http://pointfree.io/), aber bedenken Sie, dass Code von Ihrem Betrunkenen in drei Monaten gelesen werden sollte, wann immer es möglich ist. – Zeta

Verwandte Themen