ich auf einer hList Implementierung bin zu arbeiten und ich bin fest versuchen, eine map
Funktion für sie umzusetzen. Ich habe viele verschiedene Ansätze ausprobiert, aber mit jedem erreiche ich Compiler Fehler in Bezug auf diese Funktion.Mapping über ein heterogenes Datenstruktur mit einer generischen Funktion
Es folgt ein Beispiel dafür, wie ich will Just
eine generische Funktion verwenden, um alle Elemente der Eingabedatenstruktur anzuwenden.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
-- | An input heterogenous data structure
recursivePairs :: (Int, (Char, (Bool,())))
recursivePairs = (1, ('a', (True,())))
-- | This is how I want to use it
recursivePairs' :: (Maybe Int, (Maybe Char, (Maybe Bool,())))
recursivePairs' = hMap Just recursivePairs
class HMap f input output where
hMap :: f -> input -> output
-- | A counterpart of a Nil pattern match for a list
instance HMap f()() where
hMap _ _ =()
-- | A counterpart of a Cons pattern match for a list
instance
(HMap f iTail oTail,
Apply f iHead oHead) =>
HMap f (iHead, iTail) (oHead, oTail)
where
hMap f (head, tail) = (apply f head, hMap f tail)
class Apply f input output where
apply :: f -> input -> output
instance Apply (input -> output) input output where
apply = id
Damit erhalte ich den folgenden Compiler-Fehler:
No instance for (Apply (a0 -> Maybe a0) Int (Maybe Int))
arising from a use of `hMap'
The type variable `a0' is ambiguous
Gibt es überhaupt eine Möglichkeit, dies zu lösen, und wenn nicht, dann warum?
ich glaube, das Problem ist, dass das Typsystem nicht erkennen, dass Sie bei jeder aufeinanderfolgenden Anwendung, weil Ihre Definition von '' hMap' Just' mit verschiedenen Betontypen instanziieren den gleichen 'f' hält Wiederverwendung. Das erste Mal, wenn Sie es die Art anzuwenden ist 'Int -> Vielleicht Int', das zweite Mal, wenn Sie es gelten die Art ist' Char -> Vielleicht Char'. Ich bin mir aber immer noch nicht ganz sicher, wie ich das beheben soll. –
@GabrielGonzalez Ja, das ist genau das Problem. Und wenn Sie ein fundep '| hinzufügen Input-Output -> f' zum 'Apply' Klasse, werden die Fehlermeldungen sagen, dass es für Instanzen sucht, wie' (Bool -> Vielleicht Bool) Char (Vielleicht Char) '. Ich habe darüber nachgedacht, ['cast'] zu benutzen (http://hackage.haskell.org).org/packages/archive/base/neuste/doc/html/Data-Typeable.html # v: cast), um die beiden Verwendungen von 'f' auf Typ-Ebene zu trennen, aber das fühlte sich einfach nicht sehr natürlich an abhängig von 'Typable' war auch nicht sehr verlockend. –