2016-07-03 7 views
0

Ich versuche, mit der Verwendung des "Call-Haskell-to-nichts" -Paket mit diesem Code eigene Typen zu C# exportieren:Haskell: keine Instanz für eigene Art

{-# LANGUAGE ForeignFunctionInterface #-} 
{-# LANGUAGE TemplateHaskell #-} 

module RectangleMover where 

import Foreign.C 
import FFI.Anything.TypeUncurry.Msgpack 

data Point = Point Int Int 
movePoint :: Point -> Int -> Int -> Point 
movePoint (Point x y) dx dy = Point (x + dx) (y + dy) 

data Rectangle = Rectangle { corner :: Point, width :: Int, height :: Int } 
move :: Rectangle -> Int -> Int -> Rectangle 
move [email protected](Rectangle {corner=c}) dx dy = r { corner = movePoint c dx dy } 

foreign export ccall move_export :: CString -> IO CString 
move_export :: CString -> IO CString 
move_export = export move 

Wenn ich versuche, dies zu kompilieren Datei erhalte ich die Fehlermeldung:

[1 of 1] Compiling RectangleMover (test.hs, test.o) 

test.hs:19:15: 
    No instance for (Data.MessagePack.Object.MessagePack Rectangle) 
     arising from a use of ‘export’ 
    In the expression: export move 
    In an equation for ‘move_export’: move_export = export move 

Also ich glaube, ich habe eine „Instanz“ für die „Rechteck“ Art zu schreiben. Aber was ist die korrekte Syntax dafür? Ich habe bereits versucht, hinzuzufügen:

instance Rectangle where 

bekam aber diese Fehlermeldung:

test.hs:13:10: 
    Expected a constraint, but ‘Rectangle’ has kind ‘*’ 
    In the instance declaration for ‘Rectangle’ 
+1

ich mit der Bibliothek vertraut bin, aber es sollte so etwas wie 'Beispiel Data.MessagePack.Object.MessagePack Rechteck, wo sein .....'. – chi

+0

Ich habe das versucht, jetzt bekomme ich: 'test.hs: 13: 10: Nicht im Bereich: Typ Konstruktor oder Klasse 'Data.MessagePack.Object.MessagePack'' – ManzMoody

+0

Sie müssen wahrscheinlich' Data.MessagePack.Object importieren 'und benutze' instance MessagePack Rectangle where' – chi

Antwort

1

Schließlich löste ich dies mit Hilfe von ErikR (How to derive instances of Data.Messagepack 1.0.0). Hier ist der endgültige Code:

{-# LANGUAGE ForeignFunctionInterface #-} 
{-# LANGUAGE DeriveGeneriC#-} 

module RectangleMover where 

import Foreign.C 
import FFI.Anything.TypeUncurry.Msgpack 
import qualified Data.MessagePack as MP 
import Data.MessagePack.Object 
import Data.MessagePack.Aeson 
import Data.Aeson 
import GHC.Generics 

instance ToJSON Point 
instance FromJSON Point 
data Point = Point Int Int deriving (Generic, Show) 
movePoint :: Point -> Int -> Int -> Point 
movePoint (Point x y) dx dy = Point (x + dx) (y + dy) 

instance ToJSON Rectangle 
instance FromJSON Rectangle 
data Rectangle = Rectangle { corner :: Point, width :: Int, height :: Int } deriving (Generic, Show) 
move :: Rectangle -> Int -> Int -> Rectangle 
move [email protected](Rectangle {corner=c}) dx dy = r { corner = movePoint c dx dy } 

toMsgPack :: Rectangle -> Maybe MP.Object 
toMsgPack = decode . encode 

p = Point 1 2 
rect = Rectangle p 10 20 
test = toMsgPack (rect) 
2

Zunächst einmal müssen Sie Data.MessagePack.Object importieren. Das bringt die Klasse MessagePack in den Geltungsbereich.

Dann müssen Sie sagen:

instance MessagePack Rectangle where 
    toObject rect = 
     -- Insert your implementation here, returning an Object 
    fromObject obj = 
     -- Insert your implementation here, returning a Maybe Rectangle 

dies vergleichen mit der Dokumentation der MessagePack class.

+0

Leider bin ich sehr neu in Haskell. Was wäre die Implementierung von toObject und fromObject in diesem Fall? – ManzMoody

+0

Werfen Sie einen Blick auf den Quellcode für die Instanzen in Data.MessagePack.Object für einige Ideen. Es ist von der Dokumentationsseite verlinkt. –

Verwandte Themen