【问题标题】:How to define dot product in Haskell a pointfree style?如何在 Haskell 中将点积定义为无点风格?
【发布时间】:2018-03-26 11:05:52
【问题描述】:

真的,我想找出更通用的解决方案,即在单个功能点中使用 zipwith 组合折叠。

zWMult :: Num c => [c] -> [c] -> [c]
zWMult = zipWith (*)

foldPl0 :: Num c => [c] -> c
foldPl0 = foldl (+) 0

当我使用争论时,我得到了正确的解决方案

dPr x y = foldPl0 (zWMult x y)
dPr x y = foldPl0 $ zWMult x y

但是不知道如何在没有参数的情况下自然地组合这些。这两个都失败了:

Prelude> :{
Prelude| let dPr1 :: Num c => [c] -> [c] -> c
Prelude|     dPr1 = fPl0 $ zWMult
Prelude| :}

<interactive>:171:19:
Couldn't match expected type ‘[[c] -> [c] -> c]’
            with actual type ‘[Integer] -> [Integer] -> [Integer]’
Relevant bindings include
  dPr1 :: [c] -> [c] -> c (bound at <interactive>:171:5)
Probable cause: ‘zWMult’ is applied to too few arguments
In the second argument of ‘($)’, namely ‘zWMult’
In the expression: fPl0 $ zWMult

Prelude> :{
Prelude| let dPr1 :: Int c => [c] -> [c] -> c
Prelude|     dPr1 = foldPl0 $ zWMult
Prelude| :}

<interactive>:11:13:
‘Int’ is applied to too many type arguments
In the type signature for ‘dPr1’: dPr1 :: Int c => [c] -> [c] -> c

还有

dPr2 = foldPl0 . zWMult

编辑: 很酷,如果您想更全面地了解下面的解决方案,应该交叉参考这篇文章。 What does (f .) . g mean in Haskell?

【问题讨论】:

  • 您可以使用pointfree.io 转换为pointfree。小心使用,因为无点很容易变成混淆。

标签: haskell linear-algebra


【解决方案1】:

从更简单的版本开始:

dot x y = sum (zipWith (*) x y)

您可以将带有函数组合的\x -&gt; f (g x) 转换为f . g

dot x = sum . zipWith (*) x

f . g 表示(.) f g

dot x = (sum.) (zipWith (*) x)

你可以将\x -&gt; f (g x)与函数组合转换为f . g

dot = (sum.) . zipWith (*)

【讨论】:

  • 虽然 (f .) . g 成语是用 2 参数组合一个 1 参数函数的常用无点方法,但它也可以写成 fmap sum . zipWith (*) 甚至 fmap sum &lt;$&gt; zipWith (*),我find 比 (.) 的部分应用更具描述性,因为虽然 fmap(-&gt;) 仿函数中等同于组合,但它说明了这样一个事实,即您通过忽略参数(一个fmap 每个参数)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-28
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2019-06-06
相关资源
最近更新 更多