Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何使用多个';数据';其中一个为';推导';从类型函数开始?_Json_Haskell_Serialization - Fatal编程技术网

Json 如何使用多个';数据';其中一个为';推导';从类型函数开始?

Json 如何使用多个';数据';其中一个为';推导';从类型函数开始?,json,haskell,serialization,Json,Haskell,Serialization,我正在努力使以下代码正常工作(好吧,首先编译!) 所以我必须启用FlexibleContexts才能执行数据(表示a),但它仍然不起作用 我有一个错误: src/Orexio/Radix.hs:21:33: Could not deduce (Data a0) arising from a use of `query' from the context (Data a, Resource a,

我正在努力使以下代码正常工作(好吧,首先编译!)

所以我必须启用
FlexibleContexts
才能执行
数据(表示a)
,但它仍然不起作用

我有一个错误:

src/Orexio/Radix.hs:21:33:
    Could not deduce (Data a0) arising from a use of `query'
    from the context (Data a,
                      Resource a,
                      Endpoint a,
                      Data (Representation a))
      bound by the type signature for
                 bind :: (Data a, Resource a, Endpoint a,
                          Data (Representation a)) =>
                         Binding a
      at src/Orexio/Radix.hs:20:9-78
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Data HelloWorld -- Defined at src/Orexio/Radix.hs:29:29
      instance Data () -- Defined in `Data.Data'
      instance (Data a, Data b) => Data (a, b) -- Defined in `Data.Data'
      ...plus 42 others
    In the second argument of `($)', namely `query x'
    In the expression: binding $ query x
    In the first argument of `Binding', namely
      `(\ x -> binding $ query x)'
老实说,我有点迷路了,我肯定错过了什么,但是什么

以下是我激活的其他扩展:
DeriveDataTypeable
存在量化
NoMonomorphismRestriction
类型族


提前谢谢

看起来
绑定a
应该是一个将
a
类型的值转换为
表示a
类型的值或错误消息的函数。但是,由于输入和输出都是JSON编码的,因此它们都具有类型
JSValue
;他们的类型根本没有提到
a

data Binding a = Binding (JSValue -> Either String JSValue)
没有任何信息表明那些
JSValue
s代表什么类型

bind
的定义中,编译器知道返回类型是
Binding a
,但该类型与
JSValue
s的类型之间没有联系。特别是,编译器无法推断
fromJSON
应返回
a
,而
toJSON
应采用
表示法a
。要解决此问题,请将显式类型签名添加到
绑定
查询


有时让人困惑的一个细节是如何告诉GHC类型变量范围。这需要
ScopedTypeVariables
扩展名。将
forall a.
添加到
bind
的类型签名中,并将
forall.
添加到
bind
正文中的其他类型签名中,以便变量
a
的范围正确。

类型错误的本质是这一行:“类型变量'a0'不明确”

(免责声明:我试图在回答中避免使用行话。)

为了理解这里发生了什么,我建议将
绑定
查询
绑定浮动到顶层。如果您随后注释掉
bind
binding,他们将成功地进行打字检查。GHC推断出以下类型

*Orexio.Radix> :i query
query :: Data a => JSValue -> Result a
*Orexio.Radix> :i binding
binding ::
  (Data (Representation a), Endpoint a, Resource a) =>
  Result a -> Either String JSValue
您的错误主要是由
bind
定义中的表达式
\x->binding(query x)
引起的。请注意,类型变量
a
仅出现在
binding
域和
query
范围内。因此,当你创作它们时,会发生两件事

  • 类型变量未确定;它的“价值”仍然未知

  • 无法从的类型访问类型变量 作文对于我们的非正式用途,该类型是
    JSValue->
    字符串JSValue

  • GHC会引发错误,因为类型变量在合成过程中未确定(即1),将来也无法确定(结果为2)

    Haskell中该问题的一般形式更为常见,称为“
    show
    -
    read
    问题”;在哈斯克尔的真实世界中搜索“模棱两可”。(有些人也可能称之为“太多多态性”。)

    正如您和Sjoerd所确定的(以及RWH章节所解释的),您可以通过在应用
    绑定之前将类型归因于
    查询的结果来修复此类型错误。在不了解语义的情况下,我假设您希望此“隐藏”类型变量
    a
    绑定
    类型构造函数的参数相同。因此,下面的方法是可行的

    bind :: forall b.
     (Data b, Resource b, Endpoint b, Data (Representation b)) => Binding b
    bind = Binding (\x -> binding $ (query x :: Result b))
    
    这种归属消除了类型变量
    a
    ,将其完全替换为
    Result b
    。请注意,与
    a
    不同,
    b
    保持不确定状态是可以接受的,因为它在顶级类型中是可访问的;使用
    bind
    可以分别确定
    b

    第一种解决方案需要给
    bind
    一个明确的签名,这有时会非常繁重。在本例中,由于单态限制,您可能已经需要该类型签名。但是,如果
    bind
    接受了一个参数(但仍然显示出这个不明确的类型变量错误),您仍然可以通过使用如下解决方案依赖类型推断

    dummy_ResultType :: Binding a -> Result a
    dummy_ResultType = error "dummy_ResultType"
    
    bind () = result where
      result = Binding (\x -> binding $ (query x `asTypeOf` dummy))
      dummy = dummy_ResultType result
    
    (如果使用
    error
    会让您担心,请参阅。)

    或者用一些习语来换取直截了当:

    withArgTypeOf :: f x -> g x -> f x
    withArgTypeOf x _ = x
    
    bind () = result where
      result = Binding (\x -> binding (query x `withArgTypeOf` result))
    
    现在推理起作用了

    *Orexio.Radix> :i bind
    bind ::
      (Data (Representation a), Data a, Endpoint a, Resource a) =>
      () -> Binding a
    
    请放心,GHC会在类型检查后快速确定定义实际上不是递归的


    HTH.

    遵循GHC给您的建议:“可能的修复:添加一个类型签名来修复这些类型变量”@SjoerdVisscher我试图将它们放在不同的位置(在查询RHS和绑定RHS中),但没有成功。你会把它们放在哪里?谢谢你的回答我现在对这个问题有了更好的理解,但在添加类型注释后我仍然在努力,以下是我现在拥有的:但它仍然没有编译:-(@Alois,从绑定和查询中删除孔和约束。使用孔可以创建新的类型变量,但关键是使用
    bind
    签名中的
    a
    。@AloisCochard,还有,您是否打开了ScopedTypeVariables?@SjoerdVisscher awesome让它工作了,我应该读更多关于作用域如何工作的内容!thanks很多:-)
    *Orexio.Radix> :i bind
    bind ::
      (Data (Representation a), Data a, Endpoint a, Resource a) =>
      () -> Binding a