- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 get
函数添加到 wiki 中描述的通用序列化中。 。有些部分看起来很简单,但有一些地方我非常不确定要写什么,毫不奇怪,我遇到了编译错误。我已经查看了原始论文以及 cereal
中的实现,但这些资源有点超出我的理解范围。如果我能让这个简单的示例正常工作,我将更好地理解如何使用泛型。
请参阅下面的第 33 行、第 41 行、第 43 行和第 54 行。
{-# LANGUAGE DefaultSignatures, DeriveGeneric, TypeOperators, FlexibleContexts #-}
import GHC.Generics
import Data.Bits
data Bit = O | I deriving Show
class Serialize a where
put :: a -> [Bit]
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]
put a = gput (from a)
get :: [Bit] -> (a, [Bit])
default get :: (Generic a, GSerialize (Rep a)) => [Bit] -> (a, [Bit])
get xs = (to x, xs')
where (x, xs') = gget xs
class GSerialize f where
gput :: f a -> [Bit]
gget :: [Bit] -> f a
-- | Unit: used for constructors without arguments
instance GSerialize U1 where
gput U1 = []
gget xs = U1
-- | Constants, additional parameters and recursion of kind *
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where
gput (a :*: b) = gput a ++ gput b
gget xs = (a :*: b, xs'') -- LINE 33
where (a, xs') = gget xs
(b, xs'') = gget xs'
-- | Meta-information (constructor names, etc.)
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where
gput (L1 x) = O : gput x
gput (R1 x) = I : gput x
gget (O:xs) = (L1 x, xs') -- LINE 41
where (x, xs') = gget xs
gget (I:xs) = (R1 x, xs') -- LINE 43
where (x, xs') = gget xs
-- | Sums: encode choice between constructors
instance (GSerialize a) => GSerialize (M1 i c a) where
gput (M1 x) = gput x
gget = M1 . gget
-- | Products: encode multiple arguments to constructors
instance (Serialize a) => GSerialize (K1 i a) where
gput (K1 x) = put x
gget xs = K1 . get -- LINE 54
instance Serialize Bool where
put True = [I]
put False = [O]
get (I:xs) = (True, xs)
get (O:xs) = (False, xs)
--
-- Try it out...
--
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf
deriving (Generic, Show)
instance (Serialize a) => Serialize (UserTree a)
main = do
let xs = put True
print (fst . get $ xs :: Bool)
let ys = put (Leaf :: UserTree Bool)
print (fst . get $ ys :: UserTree Bool)
let zs = put (Node False Leaf Leaf :: UserTree Bool)
print (fst . get $ zs :: UserTree Bool)
错误如下:
amy11.hs:33:13:
Couldn't match expected type `(:*:) a b a1'
with actual type `((:*:) f2 g2 p3, t2)'
In the expression: (a :*: b, xs'')
In an equation for `gget':
gget xs
= (a :*: b, xs'')
where
(a, xs') = gget xs
(b, xs'') = gget xs'
In the instance declaration for `GSerialize (a :*: b)'
amy11.hs:41:17:
Couldn't match expected type `(:+:) a b a1'
with actual type `((:+:) f0 g0 p1, t0)'
In the expression: (L1 x, xs')
In an equation for `gget':
gget (O : xs)
= (L1 x, xs')
where
(x, xs') = gget xs
In the instance declaration for `GSerialize (a :+: b)'
amy11.hs:43:17:
Couldn't match expected type `(:+:) a b a1'
with actual type `((:+:) f1 g1 p2, t1)'
In the expression: (R1 x, xs')
In an equation for `gget':
gget (I : xs)
= (R1 x, xs')
where
(x, xs') = gget xs
In the instance declaration for `GSerialize (a :+: b)'
amy11.hs:54:13:
Couldn't match expected type `K1 i a a1'
with actual type `[Bit] -> K1 i0 (a0, [Bit]) p0'
In the expression: K1 . get
In an equation for `gget': gget xs = K1 . get
In the instance declaration for `GSerialize (K1 i a)'
Failed, modules loaded: none.
最佳答案
主要问题是您的gget
的类型与您的get
的类型不兼容。你是这么说的
get :: [Bit] -> (a, [Bit])
那么,相应地,你应该有
gget :: [Bit] -> (f a, [Bit])
您实际上在求和和乘积实例中做了正确的事情,但在 U1
和 K1
的情况下需要进行更正。
为了完整起见,您的代码版本进行类型检查:
{-# LANGUAGE DefaultSignatures, DeriveGeneric, TypeOperators, FlexibleContexts #-}
import GHC.Generics
import Data.Bits
data Bit = O | I deriving Show
class Serialize a where
put :: a -> [Bit]
default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]
put a = gput (from a)
get :: [Bit] -> (a, [Bit])
default get :: (Generic a, GSerialize (Rep a)) => [Bit] -> (a, [Bit])
get xs = (to x, xs')
where (x, xs') = gget xs
class GSerialize f where
gput :: f a -> [Bit]
gget :: [Bit] -> (f a, [Bit])
-- | Unit: used for constructors without arguments
instance GSerialize U1 where
gput U1 = []
gget xs = (U1, xs)
-- | Constants, additional parameters and recursion of kind *
instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where
gput (a :*: b) = gput a ++ gput b
gget xs = (a :*: b, xs'') -- LINE 33
where (a, xs') = gget xs
(b, xs'') = gget xs'
-- | Meta-information (constructor names, etc.)
instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where
gput (L1 x) = O : gput x
gput (R1 x) = I : gput x
gget (O:xs) = (L1 x, xs') -- LINE 41
where (x, xs') = gget xs
gget (I:xs) = (R1 x, xs') -- LINE 43
where (x, xs') = gget xs
-- | Sums: encode choice between constructors
instance (GSerialize a) => GSerialize (M1 i c a) where
gput (M1 x) = gput x
gget xs = (M1 x, xs')
where (x, xs') = gget xs
-- | Products: encode multiple arguments to constructors
instance (Serialize a) => GSerialize (K1 i a) where
gput (K1 x) = put x
gget xs = (K1 x, xs') -- LINE 54
where (x, xs') = get xs
instance Serialize Bool where
put True = [I]
put False = [O]
get (I:xs) = (True, xs)
get (O:xs) = (False, xs)
--
-- Try it out...
--
data UserTree a = Node a (UserTree a) (UserTree a) | Leaf
deriving (Generic, Show)
instance (Serialize a) => Serialize (UserTree a)
main = do
let xs = put True
print (fst . get $ xs :: Bool)
let ys = put (Leaf :: UserTree Bool)
print (fst . get $ ys :: UserTree Bool)
let zs = put (Node False Leaf Leaf :: UserTree Bool)
print (fst . get $ zs :: UserTree Bool)
关于generics - 使用 GHC.Generics 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17675054/
runghc 和 ghc 有什么区别? 我运行了一个简短的程序,似乎可以用两者编译,除了我用 runghc 得到了以下内容,但不是普通的 ghc: error: Variable not in sco
如果 friend 想要运行我的 Haskell 二进制文件,他是否必须先安装 Haskell,还是可以立即自行运行二进制文件? Mac、Windows 和 Linux 上的答案相同吗? 最佳答案 G
ffunction glMultiDrawElements 需要一个指向指针的指针作为其参数之一。如何从 StorableArray Int a 获取 Ptr(Ptr a) ? 最佳答案 您需要先将索
module Has (r,p,s) where import Prelude ((==),Bool(..),otherwise,(||),Eq) import qualified Data.List
我已经构建了 ghc-HEAD,我想尝试构建所有的 stackage lts 或 nightly 看看它能做多少。 无论我说什么都无法说服 stack 使用我的新 ghc 构建任何东西。我尝试设置如下
我正在使用 Emacs (24.3.1) 在 haskell-mode 中与 ghc-mod 一起使用 Haskell。 现在除了一件烦人的事情外,一切都很好: GHC 信息缓冲区中的每个输出仅包含第
为什么升级到 OSX Mavericks 后我的 GHC 7.6.3 不能工作? 最佳答案 花了很长时间才弄清楚如何同时使用 OSX 10.9 和 GHC 7.6.3,这里有一些技巧可以帮助您重新构建
我有一个带有 cabal 文件的主要 Haskell 可执行程序。在那里,我指定 ghc-options . 这个可执行文件链接到野外的其他库。请问ghc-options忽略这些库的 cabal 文件
我有一个使用 -Wall 编译的库,并且我有一个使用 -Wall -Wno-incomplete-patterns 的测试套件 当我使用 stack ghci --test 启动 ghci 时,ghc
我正在尝试使用以下脚本在 Windows 上安装 GHC(并将 ghc 放在路径中),但是当我尝试运行 ghci --version 时它失败了。我认为脚本有问题。 install: - ps:
我在 $HOME 中安装了 ghc-7.2.2 unknown linux tar.bz2在archlinux上。 在使用 cabal-dev 成功安装多个软件包后,尝试安装例如。我得到的解析数字、文
想法 我正在写 DSL ,编译为 Haskell。 该语言的用户可以定义自己的不可变数据结构和相关函数。关联函数是指属于数据结构的函数。 例如,用户可以编写(在“pythonic”伪代码中): dat
(我的问题是在没有 haskell-platform、ghc、cabal 等的情况下分发二进制文件) 我需要部署一个结构良好的 haskell 应用程序(Yesod 脚手架),但我有磁盘空间限制。 G
我试图将 Cygwin 安装程序指向 http://haskell.org/ghc/cygwin ,但安装程序无法找到 setup.ini.sig。如果可能的话,我该如何编辑我的 .bashrc 以引
我有一个现有的 Haskell 函数,它使用 GHC API 从模块中动态加载已编译的代码。它基于博客文章中的代码 Dynamic Compilation and Loading of Modules
我使用:Ubuntu 上的 GHC 7.6.3(通过 apt-get install haskell-platform) 从当前存储库安装它。 正在尝试安装ghc-mod ,因为我的 ide 插件需要
AFAIK,有两种方法可以在 Haskell 中获取用于调试的调用堆栈: 添加 HasCallStack代码中的约束 使用 ghc -prof -fprof-auto-top 编译代码 我的测试代码:
我想用 64 位 GHC 构建 32 位 DLL。这是最小的例子。 测试.hs {-# LANGUAGE ForeignFunctionInterface #-} module Test where
ghc-gc-tune 0.2.1 可以与 ghc 7.4.1 一起使用吗?看来 ghc-gc-tune 已经有一段时间没有更新了,可能只适用于 ghc 6.x?我找不到任何可靠的信息。 我收到以下错
语言扩展 ExplicitForall 使得使用 forall 绑定(bind)类型变量成为可能但不是必需的。 例如,下面的程序可以编译 {-# LANGUAGE ExplicitForAll #-}
我是一名优秀的程序员,十分优秀!