Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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
如何将函数应用于haskell中构造函数内的值?_Haskell - Fatal编程技术网

如何将函数应用于haskell中构造函数内的值?

如何将函数应用于haskell中构造函数内的值?,haskell,Haskell,我将构造函数定义为 data MuOp = N (Name, Name) | QN (QName, QName) | QO (QOp, QOp) | E (Exp, Exp) | D (Decl, Decl) | L (Literal, Literal) | G (GuardedRhs, GuardedRhs) 我对元组有一些操作,比如 same :: MuOp -

我将构造函数定义为

data MuOp = N  (Name, Name)
          | QN (QName, QName)
          | QO (QOp, QOp)
          | E  (Exp, Exp)
          | D  (Decl, Decl)
          | L  (Literal, Literal)
          | G  (GuardedRhs, GuardedRhs)
我对元组有一些操作,比如

same :: MuOp -> Bool
same (N (a,b)) = a == b
same (QN (a,b)) = a == b
same (QO (a,b)) = a == b
same (E (a,b)) = a == b
same (D (a,b)) = a == b
same (L (a,b)) = a == b
same (G (a,b)) = a == b
然而,对于多个函数重复它看起来很难看。有没有办法定义一些函数,比如
apply
where

apply :: ((a,a) -> c) -> MuOp -> c
apply f (N (a,b)) = f (a, b)
apply f (QN (a,b)) = f (a, b)
apply f (QO (a,b)) = f (a, b)
apply f (E (a,b)) = f (a, b)
apply f (D (a,b)) = f (a, b)
apply f (L (a,b)) = f (a, b)
apply f (G (a,b)) = f (a, b)
所以我可以说
same=apply(\(a,b)->a==b)
或者
feqc->apply(\(a,b)->a==c)

我当前的定义产生了这个错误

Couldn't match expected type ‘a’ with actual type ‘Name’
  ‘a’ is a rigid type variable bound by
      the type signature for apply :: ((a, b) -> c) -> MuOp -> c
      at src/Test/MuCheck/MuOp.hs:28:10
Relevant bindings include
  f :: (a, b) -> c (bound at src/Test/MuCheck/MuOp.hs:29:7)
  apply :: ((a, b) -> c) -> MuOp -> c
    (bound at src/Test/MuCheck/MuOp.hs:29:1)
In the expression: a
In the first argument of ‘f’, namely ‘(a, b)’

仔细考虑你对
应用的定义:在每种情况下,所有
b
变量的类型是否相同?请记住,尽管
apply
是一个多态函数,但调用方可以决定类型变量
a
将是什么(即错误消息中的“刚性类型变量”)

例如,请看以下两种情况:

apply :: ((a, a) -> c) -> MuOp -> c
apply f (N  (a, b)) = f (a, b)
apply f (QN (a, b)) = f (a, b)
...
第一行
a
b
都是
Name
类型,但第二行
a
b
都是
QName
类型。由于调用者可以决定变量
a
的类型,因此您实际上无法在
Name
QName
之间任意选择

解决方案是使用排名2的类型:

{-# Language Rank2Types #-}

apply :: (forall a . Eq a => (a, a) -> c) -> MuOp -> c
apply f (N  (a, b)) = f (a, b)
apply f (QN (a, b)) = f (a, b)
...

所有a.
的先前隐式量词
已显式化,并推到函数箭头的左侧。(另外,添加了
Eq
约束,但这只是一个次要细节。)这样做,您就允许被调用方(即
apply
)用满足
Eq
约束的任何类型实例化类型变量
a

您明白为什么会出现该错误吗?理解许多可能的答案是很重要的。@ThomasM.DuBuisson抱歉,一直在试验并粘贴错误的定义,但我的问题也适用。@rahul:仔细考虑你对
apply
的定义:所有
b
变量在每种情况下都是相同类型的吗?请记住,尽管
apply
是一个多态函数,但调用方可以决定类型变量
a
将是什么(也称为“刚性类型变量”)。@rahul:您需要使用Rank2Types扩展。这样,您可以请求一个函数,在该函数中被调用方(
apply
)可以任意选择使用
==
的哪个专门化。等式a=>(a,a)->c
看起来非常类似于
Bool->c
:除了检查两对组件是否相等,
f
还能做什么?我的感觉是,这是由参数保证的。如果是这样的话,没有多少有意义的
f
s可以传递给
apply
:-/它可以推广到
apply::Q=>Proxy c->(对于所有的a.ca=>a->a->c)->MuOp->c
,其中
Q
是一个约束,表示MuOp中的每个类型都是
c
的实例。