ich diese Funktion zu definieren versuchte, drei Listen von Paaren neu zu formieren:RankNTypes: gelten die gleiche Funktion zu Paaren unterschiedlicher Typen
{-# LANGUAGE RankNTypes #-}
mapAndZip3 :: (forall x. x -> f x) -> [a] -> [b] -> [c]
-> [(f a, f b, f c)]
mapAndZip3 f la lb lc = zipWith3 (\a b c -> (f a, f b, f c)) la lb lc
main = do
let x = mapAndZip3 (fst) [(1,"fruit"), (2,"martini")]
[("chips","fish"),("rice","steak")]
[(5,"cake"),(4,"pudding")]
print x -- was expecting [(1,"chips",5), (2,"rice",4)]
Zuerst habe ich nicht die RankNTypes
oder die forall
umfassen, aber dann nach dem einsehen this, nämlich die liftTup
definition, ich dachte, dass es genug sein sollte.
Aber klar, es war nicht, wie ich noch einen Fehler:
mapAndZip3.hs:8:25:
Couldn't match type `x' with `(f0 x, b0)'
`x' is a rigid type variable bound by
a type expected by the context: x -> f0 x at mapAndZip3.hs:8:13
Expected type: x -> f0 x
Actual type: (f0 x, b0) -> f0 x
In the first argument of `mapAndZip3', namely `(fst)'
ich eindeutig ein begrenztes Verständnis des forall
Schlüsselwort, aber von dem, was ich verstand es soll in diesem Fall erlauben für f
jeden Typ zu akzeptieren. Was ich nicht verstehe ist: Einmal innerhalb eines gegebenen Kontexts und einmal verwendet, wird die Definition für den verbleibenden Kontext "fixiert"?
Es scheint nicht so, denn wenn ich "Chips" und "Reis" mit Ints ersetze, beschwert sich der Compiler immer noch, also nehme ich an, dass etwas falsch ist (natürlich, wenn ich den Typ Annotation von entferne mapAndZip3
in diesem letzten Fall funktioniert alles, weil die Signatur auf mapAndZip3 :: (a -> t) -> [a] -> [a] -> [a] -> [(t, t, t)]
vereinfacht wird, aber das ist nicht was ich will).
Ich fand auch diesen question, kann aber nicht wirklich machen, wenn diese das gleiche Problem oder nicht, da die Funktion ich nicht id
anzuwenden bin versucht, aber fst
oder snd
, Funktionen, die tatsächlich verschiedene Arten (a -> b)
zurück.
Danke! Es fiel mir wirklich schwer, "eine" richtige Antwort zu wählen, da beide tatsächlich erklären, dass dies nicht möglich ist. Und obwohl ich Daniel Fischer sehr gerne antworte, dass er am einfachsten zu verstehen ist, gab mir links über die Antwort einen zusätzlichen Kontext. Prost zu beiden! – jcristovao