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 在哈斯克尔用2+;论据_Haskell_Currying_Pointfree_Tacit Programming - Fatal编程技术网

Haskell 在哈斯克尔用2+;论据

Haskell 在哈斯克尔用2+;论据,haskell,currying,pointfree,tacit-programming,Haskell,Currying,Pointfree,Tacit Programming,我开始学习Haskell,所以我也需要了解咖喱(这也是我第一次看到这种技巧)。我想我了解了在某些情况下它是如何工作的,在这种情况下,咖喱化只“消除”了一个参数。就像在下一个例子中,我试图计算4个数字的乘积。 这是未载波函数: prod :: Integer->Integer->Integer->Integer->Integer prod x y z t = x * y * z * t prod' :: Integer->Integer->Integer-&g

我开始学习Haskell,所以我也需要了解咖喱(这也是我第一次看到这种技巧)。我想我了解了在某些情况下它是如何工作的,在这种情况下,咖喱化只“消除”了一个参数。就像在下一个例子中,我试图计算4个数字的乘积。 这是未载波函数:

prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
prod :: Integer -> Integer -> Integer -> Integer -> Integer
prod x y z t = x * y * z * t
prod2 = prod 2
这是curried函数:

prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
prod :: Integer -> Integer -> Integer -> Integer -> Integer
prod x y z t = x * y * z * t
prod2 = prod 2
但是我不明白我怎么能继续这个动态,比如用两个参数做同一个函数,等等:

prod'' :: Integer->Integer->Integer->Integer->Integer
prod'' x y =
这是未载波函数:

prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
prod :: Integer -> Integer -> Integer -> Integer -> Integer
prod x y z t = x * y * z * t
prod2 = prod 2
这已经是一个常用的函数了。事实上,Haskell中的所有函数都是自动转换的。实际上,您在这里编写了一个函数,该函数如下所示:

prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod = \x -> (\y -> (\z -> (\t -> x * y * z * t)))
因此,Haskell将生成如下函数:

prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod :: Integer -> (Integer -> (Integer -> (Integer -> Integer)))
prod = \x -> (\y -> (\z -> (\t -> x * y * z * t)))
事实上,例如,我们可以生成这样的函数:

prod :: Integer->Integer->Integer->Integer->Integer
prod x y z t = x * y * z * t
prod' :: Integer->Integer->Integer->Integer->Integer
prod' x y z = (*) (x*y*z)
prod :: Integer -> Integer -> Integer -> Integer -> Integer
prod x y z t = x * y * z * t
prod2 = prod 2
这将具有以下类型:

prod2 :: Integer -> (Integer -> (Integer -> Integer))
prod2 = prod 2
我们可以继续:

prod2_4 :: Integer -> (Integer -> Integer)
prod2_4 = prod2 4
最终:

prod2_4_6 :: Integer -> Integer
prod2_4_6 = prod2_4 6
编辑

功能
prod'
带有:

prod'' x y = (*) ((*) (x*y))
因为这意味着将
(*)(x*y)
与下一个参数相乘。但是
(*)(x*y)
是一个函数。你只能乘数字。严格地说,你可以用数字来表示函数。但Haskell编译器因此抱怨:

Prelude> prod'' x y = (*) ((*) (x*y))

<interactive>:1:1: error:
    • Non type-variable argument in the constraint: Num (a -> a)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        prod'' :: forall a.
                  (Num (a -> a), Num a) =>
                  a -> a -> (a -> a) -> a -> a
Prelude>prod''x y=(*)((*)(x*y))
:1:1:错误:
•约束中的非类型变量参数:Num(a->a)
(使用flexibleContext允许此操作)
•检查推断类型时
产品“”::对于所有a。
(数值(a->a),数值a)=>
a->a->(a->a)->a->a
因此,这里的目标是以函数
a->a
作为第一个操作数来执行操作,但该函数不是
Num
typeclass的实例。

prod x y z t  =    x * y * z * t
              =   (x * y * z) * t
              =  (*) (x * y * z) t
因此,eta降低(我们将
foo x=bar x
替换为
foo=bar

因此,通过再次降低eta

prod x y      =   (*) . (*) (x * y)
这里,
()
是函数组合运算符,定义为

(f . g) x  =  f (g x)
你所问的是所谓的无点风格。“无点”是指“没有明确提及[隐含]参数”(“点”是数学家对“参数”的行话)

“Currying”是一个正交的问题,尽管Haskell是一种curryd语言,使得这样的定义——以及Willem的回答中所示的部分应用程序定义——更容易编写。“Currying”意味着函数一次只取一个参数,因此很容易将函数的一部分应用于一个值

我们可以继续提取最后一个参数的过程,这样就可以通过进一步减少eta来消除它。但它通常会迅速导致越来越多的模糊代码,比如
prod=(((*)。(*))。(*)

这是因为编写的代码是对固有的二维(甚至更高维)计算图形结构的一维编码

  prod =           
                  /
                 *
                / \
               *   
              / \
         <-- *   
              \
表示同样清晰的外观,只是稍微重新排列,图形结构

              / 
         <-- *   
              \ /
               *
                \ /
                 *
                  \
/

首先,您需要认识到Haskell中的每个函数最多有一个参数。@bipll和一个参数。注意,每个函数只有一个参数。@leftaroundabout
zero=0
@bipll这不是函数。
zero
的类型中没有
->
。但这不是问题中的问题。@WillNess:它要求生成一个curried函数,而不是一个无点函数。请查看类型。:)这已经不是第一次询问者对术语感到困惑了。@Willenss:我真的不知道这里的类型做了什么:)特别是因为Haskell的语法已经被套用了,当然,不需要改变类型。
prod'
prod'
的类型都是
Integer->Integer->Integer->Integer->Integer->Integer
。部分应用示例的类型不同。所以我把这解释为OP对术语的混淆。