2016-04-11 6 views
4

Ich befolge das Tutorial zum Erstellen einer generischen "encode" -Funktion für Datentypen von hackage documentation für GHC.Generics. Ich habe Kopie kleistert der Code bis zu (und einschließlich) dem Abschnitt „Die Wrapper und generische Standard“, aber ich erhalte den folgenden Fehler:Haskell/GHC Generics Dokumentation Beispiel fehlt eine Typklassenbeschränkung?

Main.hs:35:14: 
    Could not deduce (Encode' (Rep a)) arising from a use of ‘encode'’ 
    from the context (Encode a) 
     bound by the class declaration for ‘Encode’ 
     at Main.hs:(32,1)-(35,29) 
    or from (Generic a) 
     bound by the type signature for encode :: Generic a => a -> [Bool] 
     at Main.hs:33:13-23 
    In the expression: encode' (from x) 
    In an equation for ‘encode’: encode x = encode' (from x) 
Failed, modules loaded: none. 

Der Code, den ich kopiert habe, ist wie folgt:

{-# LANGUAGE DeriveGeneriC#-} 
{-# LANGUAGE TypeOperators #-} 
{-# LANGUAGE DefaultSignatures #-} 
{-# LANGUAGE FlexibleContexts #-} 
{-# LANGUAGE DeriveAnyClass #-} 
module Main where 

import GHC.Generics 

class Encode' f where 
    encode' :: f p -> [Bool] 

instance Encode' V1 where 
    encode' x = undefined 

instance Encode' U1 where 
    encode' U1 = [] 

instance (Encode' f, Encode' g) => Encode' (f :+: g) where 
    encode' (L1 x) = False : encode' x 
    encode' (R1 x) = True : encode' x 

instance (Encode' f, Encode' g) => Encode' (f :*: g) where 
    encode' (x :*: y) = encode' x ++ encode' y 

instance (Encode c) => Encode' (K1 i c) where 
    encode' (K1 x) = encode x 

instance (Encode' f) => Encode' (M1 i t f) where 
    encode' (M1 x) = encode' x 

class Encode a where 
    encode :: a -> [Bool] 
    default encode :: (Generic a) => a -> [Bool] 
    encode x = encode' (from x) 

Ich denke, das Problem ist bei der endgültigen Klassendeklaration (class Encode a where ...). Ich habe es behoben, indem eine zusätzliche Einschränkung hinzufügen, um dieses zu erhalten:

class Encode a where 
    encode :: a -> [Bool]                                        
    default encode :: (Generic a, Encode' (Rep a)) => a -> [Bool] 
    encode x = encode' (from x) 

Dies scheint wie in der Werbung zu arbeiten - ich kann neue Datentypen erklären und sie mit DeriveAnyClass und deriving machen codierbar. Ich bin mir aber nicht wirklich sicher, warum meine Lösung notwendig ist. Meine Frage ist:

  • Sind die Dokumente falsch?
  • Sollte die Encode' (Rep a) Einschränkung im Beispielcode auf Hackage vorhanden sein?
  • Wenn nicht, was soll ich hinzufügen, damit der Code funktioniert?

Antwort

4

Ja, ich denke, die Dokumente sind falsch. Die Einschränkung ist erforderlich.

+0

Cool! Mit wem rede ich/wohin gehe ich, um sie zu reparieren? – statusfailed

+1

@statusfailed Eigentlich ist es bereits behoben: http://downloads.haskell.org/~ghc/master/libraries/html/base/GHC-Generics.html#g:13 (Danke an Ben Gamari). – kosmikus