2017-06-10 1 views
3
import Data.Singletons 
import Data.Singletons.TypeLits 

type family N t :: Nat where 
    N Int = 42 
    N String = 9 

foo :: (n ~ N t) => t -> Integer 
foo _ = fromSing (sing :: Sing n) 

nicht mitNat aus Art Familie Aufruf in Integer

• Could not deduce: DemoteRep * ~ Integer 
    from the context: n ~ N t 
    bound by the type signature for: 
       foo :: n ~ N t => t -> Integer 
    at mini.hs:16:1-32 
• In the expression: fromSing (sing :: Sing n) 
    In an equation for ‘foo’: foo _ = fromSing (sing :: Sing n) 

Wie kann ich es beheben?

Antwort

3

Es gibt zwei Probleme mit Ihrem Code. Erstens, (sing :: Sing n) hat n nicht im Anwendungsbereich. Sie benötigen explizit forall, um es in den Geltungsbereich zu bringen. Wenn Sie SingI möchten, müssen Sie dies sagen. GHC weiß nicht und überprüft nie, dass N tSingI für alle t ist, was übrigens nicht wahr ist: N Bool hat Art Nat aber es gibt keine SingI (N Bool).

Daher ist die Lösung:

foo :: forall t. SingI (N t) => t -> Integer 
foo _ = fromSing (sing :: Sing (N t)) 

Oder mit Typ-Anwendungen:

foo :: forall t. SingI (N t) => t -> Integer 
foo _ = fromSing (sing @_ @(N t)) 
+0

Danke, András. Es macht jetzt Sinn. Was ich nicht verstehe, ist die Fehlermeldung. Sollte sich ghc nicht beschweren, dass n in Sing n nicht gebunden ist? –

+1

@BrunoMartinez GHC betrachtet ungebundene Typvariablen als neue Variablen im Kontext und lässt Sie in späteren Typanmerkungen auf sie verweisen. So betrachtet es das "n" als "Sing n" eine neue Variable, die nicht mit dem "n" in der Signatur für "foo" zusammenhängt. –