2016-05-24 6 views
3

Ich mag fürWie implementiere ich eine faltbare Instanz für Konstante a b = Konstante a?

data Constant a b = Constant a 

Das ist mein einfacher Versuch, faltbar implementieren:

instance Foldable (Constant a) where 
    foldr f b (Constant a) = f a b 

Der Teil des Übersetzungsfehlers I verstehen will:

Couldn't match expected type ‘a1’ with actual type ‘a’ 
‘a1’ is a rigid type variable bound by the type signature for 
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b 

wie möglich sehen Sie die Faltfunktion nimmt den "Phantom-Typ" (?) a1 von der Konstante, die ich nicht zugreifen kann; Ich habe nur Zugriff auf die a.

Wie löse ich das? Bitte erkläre deine Lösung, denn ich bin ziemlich verwirrt.

Der gesamte Übersetzungsfehler ist:

try2/chap20/ex1.hs:9:30: Couldn't match expected type ‘a1’ with actual type ‘a’ … 
     ‘a’ is a rigid type variable bound by 
      the instance declaration 
      at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:8:10 
     ‘a1’ is a rigid type variable bound by 
      the type signature for 
      foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b 
      at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3 
    Relevant bindings include 
     a :: a 
     (bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:23) 
     f :: a1 -> b -> b 
     (bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:9) 
     foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b 
     (bound at /Users/moron/code/haskell/book/try2/chap20/ex1.hs:9:3) 
    In the first argument of ‘f’, namely ‘a’ 
    In the expression: f a b 
Compilation failed. 
+0

können Sie nicht. Sie können nur eine faltbare (C a) -Instanz für die Daten C a b = C b definieren. In Ihrem Fall würden Sie etwas wie 'Instanz faltbar (\ a -> Konstante a b)' brauchen, aber wir haben keine Haschell-labdas auf Typenebene. – chi

+0

Gute Frage, ich habe mich gerade gefragt, während ich versuche, foldl zu implementieren –

Antwort

9

Constant a b enthält keine b -s, so dass wir umklappen es, als ob es sich um eine leere Liste von b -s waren:

instance Foldable (Constant a) where 
    foldr f z (Constant a) = z 

a in Constant a b ist nicht relevant für die Foldable Instanz, da das betrifft nur den letzten Parameter. Daher können Sie a in Ihrer Definition nicht wirklich verwenden.

2

Ich denke, die einzige Möglichkeit ist:

data Constant a b = C a 

-- foldMap :: Monoid m => (b -> m) -> t b -> m 
instance Foldable (Constant a) where 
    foldMap f (C a) = mempty 

, die die triviale Lösung ist.

Es könnte aufschlussreich sein, um zu sehen, warum Sie es für diese Definition tun:

data Constant' a b = C' b 

-- foldMap :: Monoid m => (b -> m) -> t b -> m 
instance Foldable (Constant' a) where 
    foldMap f (C' a) = f a 

Hier t ist Constant' a, so

  • der Typ t bConstant' a b ist. Die Werte dieser Art haben die Struktur C bval für einen Wert bval vom Typ b.
  • f hat b -> m geben, so können wir f zu bval

Im anderen Fall gelten, aber wir haben keinen Wert b-f anzuwenden, so dass das Beste, was wir tun können, ist Rückkehr mempty.