Function 声明函数中函数的类型

Function 声明函数中函数的类型,function,haskell,types,Function,Haskell,Types,我有两个职能: prop_merge_check :: Ord a => [a] -> [a] -> Bool prop_merge_check xs ys = length (merge xs ys) == length (sort (xs ++ ys)) prop_unzip_check :: Ord a => [(a,b)] -> Bool prop_unzip_check xs = length (unzip xs) >= 0 如何在函数本身中声明

我有两个职能:

prop_merge_check :: Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys = length (merge xs ys) == length (sort (xs ++ ys))

prop_unzip_check :: Ord a => [(a,b)] -> Bool
prop_unzip_check xs = length (unzip xs) >= 0
如何在函数本身中声明函数的类型

我试过这种方法,但没有成功

prop_merge_check xs ys = length (merge (xs::[a]) (ys::[a])) 
                           == length (sort ( (xs::[a]) ++ (ys::[a]) ))

prop_unzip_check xs = length (unzip (xs::[(a,b)])) >= 0

这是哈斯凯尔隐式福尔的副作用。Haskell会根据需要自动将“forall”添加到所有类型签名中,这些作为“作用域”规则,将名称限制在特定区域。Haskell将您的签名解释为:

prop_merge_check :: forall a. Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys =
    length (merge (xs::forall a. [a]) (ys:: forall a. [a])) == (length (sort ((xs:: forall a. [a]) ++ (ys:: forall a. [a]))))
就是,;它将每个签名中的每个
a
视为一个完全不同的变量!这就是为什么它不能使类型正常工作。这是一个恼人且不明显的怪癖,但总有办法解决的

如果我们启用
ScopedTypeVariables
并在类型签名中提供显式forall,我们会告诉Haskell我们希望类型变量的作用域跨越整个函数体:

{-# LANGUAGE ScopedTypeVariables #-}
-- ^ Put that at the top of your module

prop_merge_check :: forall a. Ord a => [a] -> [a] -> Bool
prop_merge_check xs ys =
    length (merge (xs::[a]) (ys::[a])) == (length (sort ((xs::[a]) ++ (ys::[a]))))
这个版本应该编译,因为现在所有签名中的
a
被认为是相同的。我们可以一次量化多个类型变量:

prop_unzip_check :: forall a b. Ord a => [(a,b)] -> Bool
prop_unzip_check xs = length (unzip (xs::[(a,b)])) >= 0
不幸的是,如果不在顶级签名中添加显式forall,目前还没有一种简单的方法来完成这类事情,但是有一些建议可以改变这种行为。不过,他们可能不会很快到来;所以我不会让你屏住呼吸


祝你好运!您可以查阅ScopedTypeVariables和ExistentialQuantification的文档,以了解更多关于这一怪癖的信息。

我们可以一次量化多个变量;我现在也在我的答案中添加了这个解决方案;但我仍然收到编译器的一种错误,我将创建另一个问题,请您看一下好吗?我现在没有看到您提出任何其他问题;你确定你提交了吗?上面说每1.30小时只有一篇文章,所以我在等:c。也许我可以直接给你写信?我是新来的