Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.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,我需要编写一个函数,该函数接受两个约束,并返回第三个约束,该约束仅在前两个约束也满足时才满足。我可以编写一个helper函数来测试前两个约束是否返回true或false,但问题是测试可以是任何东西,所以我不能为了测试它而传入一些东西。有没有办法以某种方式组合任何类型的两个功能/约束 我希望我说的有道理。假设“constraint”是指某种谓词,您可以很容易地编写一个函数,将两个谓词组合成一个新的谓词 type Pred a = a -> Bool both :: Pred a ->

我需要编写一个函数,该函数接受两个约束,并返回第三个约束,该约束仅在前两个约束也满足时才满足。我可以编写一个helper函数来测试前两个约束是否返回true或false,但问题是测试可以是任何东西,所以我不能为了测试它而传入一些东西。有没有办法以某种方式组合任何类型的两个功能/约束

我希望我说的有道理。

假设“constraint”是指某种谓词,您可以很容易地编写一个函数,将两个谓词组合成一个新的谓词

type Pred a = a -> Bool

both :: Pred a -> Pred a -> Pred a
both p1 p2 x = p1 x && p2 x
快速测试运行:

*Main Data.Char> both odd (> 3) 5
True
*Main Data.Char> both isAlpha isUpper 'b'
False

如果您有两个类型的测试:

constraint1 :: a -> Bool
constraint2 :: b -> Bool
您希望构建第三个constriant,即两者的并集,然后只需使用
(&&&)


强制性神秘答案:

import Control.Arrow
import Data.Composition

both :: (a -> Bool) -> (a -> Bool) -> a -> Bool
both = uncurry (&&) .** (&&&)
总有一天,我会着手正确地记录我的Data.Composition库(),但基本上是
(.*)fgxyz=f(gxyz)

下面是它的工作原理(简化了&&&函数的工作原理)


我们现在已经得出了哈马尔的定义。:)

如果我正确理解了您的问题,您需要
(&&)
函数。否则我不理解你的问题。&&对函数不起作用。什么是约束?它有任何类型的签名吗?比如
::a->Bool
?我不知道怎么做,我只是给了他们更高的票数。我刚刚知道怎么做了,谢谢。那只是假设你知道类型,但实际上它是未知的,可能是任何东西。我想你必须用一个例子来澄清你的意思。嗯,这似乎有效。。。我想。但是,当您只声明了两个时,为什么它将x作为第三个周长呢?这是因为返回类型,
preda
是一个函数。我还可以编写
两个p1=\x->…
,就像我可以编写
两个p1=\p2->\x->…
。多亏了咖喱,它们是一样的!它需要返回一个函数,您的方法返回bool。如何编写它以使其返回一个函数>?这看起来不必要地复杂。普通的
liftM2(&&)
不也同样有效吗?@DanielWagner当然可以。但是我想玩
(&&&)
import Control.Arrow
import Data.Composition

both :: (a -> Bool) -> (a -> Bool) -> a -> Bool
both = uncurry (&&) .** (&&&)
(&&&) f g x = (f x, g x)
uncurry f (x,y) = f x y
(.**) f g x y z = f (g x y z)

both = uncurry (&&) .** (&&&)
-- undo infix notation
both = (.**) (uncurry (&&)) (&&&)
-- definition of .**, with f = (uncurry (&&)), g = (&&&), x = p1, y = p2, z = v
both = \p1 p2 v -> (uncurry (&&)) ((&&&) p1 p2 v) 
-- definition of &&&, with f = p1, g = p2, x = v
both = \p1 p2 v -> (uncurry (&&)) (p1 v, p2 v)
-- definition of uncurry, with f = (&&)
both = \p1 p2 v -> (\(x, y) -> (&&) x y) (p1 v, p2 v)
-- function application, bind x = p1 v, y = pw v
both = \p1 p2 v -> (&&) (p1 v) (p2 v)
-- rewrite without lambda, move && to infix position
both p1 p2 v = p1 v && p2 v