Haskell: 没有自己类型的实例
Haskell: No instance for own type
我正在尝试使用带有以下代码的 "call-haskell-to-anything" 包将自己的类型导出到 C#:
{-# 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 r@(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
当我尝试编译此文件时,我收到错误消息:
[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
所以我想我必须为 "rectangle" 类型写一个 "instance"。但是正确的语法是什么?我已经尝试添加 :
instance Rectangle where
但收到此错误消息:
test.hs:13:10:
Expected a constraint, but ‘Rectangle’ has kind ‘*’
In the instance declaration for ‘Rectangle’
首先您需要导入 Data.MessagePack.Object
。这会将 class MessagePack
纳入范围。
那你需要说:
instance MessagePack Rectangle where
toObject rect =
-- Insert your implementation here, returning an Object
fromObject obj =
-- Insert your implementation here, returning a Maybe Rectangle
将此与 MessagePack class 的文档进行比较。
最后我在 ErikR () 的帮助下解决了这个问题。
这是最终代码:
{-# 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 r@(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)
我正在尝试使用带有以下代码的 "call-haskell-to-anything" 包将自己的类型导出到 C#:
{-# 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 r@(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
当我尝试编译此文件时,我收到错误消息:
[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
所以我想我必须为 "rectangle" 类型写一个 "instance"。但是正确的语法是什么?我已经尝试添加 :
instance Rectangle where
但收到此错误消息:
test.hs:13:10:
Expected a constraint, but ‘Rectangle’ has kind ‘*’
In the instance declaration for ‘Rectangle’
首先您需要导入 Data.MessagePack.Object
。这会将 class MessagePack
纳入范围。
那你需要说:
instance MessagePack Rectangle where
toObject rect =
-- Insert your implementation here, returning an Object
fromObject obj =
-- Insert your implementation here, returning a Maybe Rectangle
将此与 MessagePack class 的文档进行比较。
最后我在 ErikR (
{-# 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 r@(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)