<=和>运算符作为函数参数

安德烈·布什曼

快速排序:

-- First variant:
qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) = left x ++ [x] ++ right x 
  where left  n = qsort [m | m <- xs, m <= n]
        right n = qsort [m | m <- xs, m  > n]

-- λ: qsort [10,2,5,3,1,6,7,4,2,3,4,8,9]
-- [1,2,2,3,3,4,4,5,6,7,8,9,10]

我看到leftright功能几乎相同。因此,我想将其改写得更短一些……

-- Second variant:
qsort' :: (Ord a) => [a] -> [a]
qsort' [] = []
qsort' (x:xs) = (srt <=) ++ [x] ++ (srt >)
  where srt f = qsort' [m | m <- xs, m f x]

但是,当我尝试将其加载到ghci

λ: :load temp
[1 of 1] Compiling Main             ( temp.hs, interpreted )

temp.hs:34:18:
    Couldn't match expected type `[a]'
                with actual type `(t0 -> [a]) -> Bool'
    Relevant bindings include
      srt :: forall t. t -> [a] (bound at temp.hs:35:9)
      xs :: [a] (bound at temp.hs:34:11)
      x :: a (bound at temp.hs:34:9)
      qsort' :: [a] -> [a] (bound at temp.hs:33:1)
    In the first argument of `(++)', namely `(srt <=)'
    In the expression: (srt <=) ++ [x] ++ (srt >)
    In an equation for qsort':
        qsort' (x : xs)
          = (srt <=) ++ [x] ++ (srt >)
          where
              srt f = qsort' [m | m <- xs, m f x]

temp.hs:34:37:
    Couldn't match expected type `[a]'
                with actual type `(t1 -> [a]) -> Bool'
    Relevant bindings include
      srt :: forall t. t -> [a] (bound at temp.hs:35:9)
      xs :: [a] (bound at temp.hs:34:11)
      x :: a (bound at temp.hs:34:9)
      qsort' :: [a] -> [a] (bound at temp.hs:33:1)
    In the second argument of `(++)', namely `(srt >)'
    In the second argument of `(++)', namely `[x] ++ (srt >)'
    In the expression: (srt <=) ++ [x] ++ (srt >)

temp.hs:35:38:
    Could not deduce (a ~ (t -> a -> Bool))
    from the context (Ord a)
      bound by the type signature for qsort' :: Ord a => [a] -> [a]
      at temp.hs:32:11-31
      `a' is a rigid type variable bound by
          the type signature for qsort' :: Ord a => [a] -> [a]
          at temp.hs:32:11
    Relevant bindings include
      m :: a (bound at temp.hs:35:29)
      f :: t (bound at temp.hs:35:13)
      srt :: t -> [a] (bound at temp.hs:35:9)
      xs :: [a] (bound at temp.hs:34:11)
      x :: a (bound at temp.hs:34:9)
      qsort' :: [a] -> [a] (bound at temp.hs:33:1)
    The function `m' is applied to two arguments,
    but its type `a' has none
    In the expression: m f x
    In a stmt of a list comprehension: m f x
Failed, modules loaded: none.
λ:

我阅读了错误消息,但仍然不理解原因...

威廉·范昂塞姆

您不应该将其f用作中缀。您可以通过放在f前面并在方括号之间表示功能来解决此问题(<=)

-- third variant:
qsort' :: (Ord a) => [a] -> [a]
qsort' [] = []
qsort' (x:xs) = (srt (<=)) ++ [x] ++ (srt (>))
  where srt f = qsort' [m | m <- xs, f m x]

这主要是因为你基本上想要做的是电话 fmx现在,默认的lambda-calculus始终首先评估左侧列出的函数。

Haskell只为操作员提供了一些语法上的便利:当您编写时a+b,您基本上写的是(+) a b(在幕后)。这是Haskell最喜欢的,但是编译器因此提供了一些功能以方便程序员。由于编写a*b+c*d比编写要容易得多(+) ((*) a b) ((*) c d),但是第二个实际上是如何在lambda微积分中编写这样的东西。

为了看到运营商的功能,你写他们括号,因此要获得的功能变的<=,你写的(<=)

编辑

正如@Jubobs所说,您也可以使用中缀,但因此需要使用反引号:

-- fourth variant:
qsort' :: (Ord a) => [a] -> [a]
qsort' [] = []
qsort' (x:xs) = (srt (<=)) ++ [x] ++ (srt (>))
  where srt f = qsort' [m | m <- xs, m `f` x]

这个问题主要是,你需要通过通过你的功能f,并且<=>不是函数,(<=)(>)是。从技术上讲,这个故事要复杂一些,但是我想这在学习基础知识时就足够了。

通过使用反引号,Haskell读取:

x `f` y

作为:

f x y

(请注意,这并不是完全正确的,因为运算符也有一个优先级*绑定比绑定更紧密+,但这更多地是过程的“细节”)。

将括号放在运算符上是相反的效果:

x o y

(o) x y

o操作员。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C-函数参数和“ <<”运算符

来自分类Dev

运算符+和float参数

来自分类Dev

参数绑定和IN运算符

来自分类Dev

示例函数和运算符> =

来自分类Dev

JSfiddle课程-函数和运算符

来自分类Dev

JavaScript 函数和 new 运算符

来自分类Dev

在std :: vector push_back()和std :: map运算符中使用&&作为参数[]

来自分类Dev

在将抽象基类作为参数的函数中,将指针和赋值运算符与派生类一起使用

来自分类Dev

将逻辑运算符(和部分表达式)传递给函数参数Python

来自分类Dev

一个参数构造函数和赋值运算符

来自分类Dev

JS绑定函数的性质和函数调用运算符

来自分类Dev

正向函数组合运算符和反向应用程序运算符

来自分类Dev

正向函数组合运算符和反向应用程序运算符

来自分类Dev

运算符重载传递和返回的参数

来自分类Dev

运算符重载和不同的模板参数

来自分类Dev

赋值运算符的下沉参数实现和语言缺陷

来自分类Dev

用于字符串参数的Javascript *和*运算符

来自分类Dev

运算符重载和不同的模板参数

来自分类Dev

标志和| =运算符的类型参数的约束

来自分类Dev

重定向运算符,标准输入和命令参数

来自分类Dev

Bash:算术扩展,参数扩展和逗号运算符

来自分类Dev

复制构造函数和运算符是否必须?

来自分类Dev

运算符<<链接和函数调用顺序

来自分类Dev

函数组合运算符(。)和fmap(<$>)之间的区别

来自分类Dev

关于转换构造函数和赋值运算符

来自分类Dev

运算符重载和非成员函数C ++

来自分类Dev

jOOQ是否支持PostgreSQL数组函数和运算符?

来自分类Dev

Java的构造函数和新运算符

来自分类Dev

子类化,赋值运算符和副本构造函数

Related 相关文章

热门标签

归档