如何在Haskell中定义dot产品是一种无点样式?

War*_*lan 2 haskell linear-algebra

真的,我想找出一个更简单的解决方案,用一个单一的功能点免费组成一个带有拉链的折叠.

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

foldPl0 :: Num c => [c] -> c
foldPl0 = foldl (+) 0
Run Code Online (Sandbox Code Playgroud)

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

dPr x y = foldPl0 (zWMult x y)
dPr x y = foldPl0 $ zWMult x y
Run Code Online (Sandbox Code Playgroud)

但是不知道如何在没有论据的情况下自然地组成这些.这两个都失败了:

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
Run Code Online (Sandbox Code Playgroud)

以及

dPr2 = foldPl0 . zWMult
Run Code Online (Sandbox Code Playgroud)

编辑:很酷,如果你想更全面地了解下面的解决方案,应该交叉参考这篇文章. 什么(f.).在Haskell中意味着什么?

Ry-*_*Ry- 7

从更简单的版本开始:

dot x y = sum (zipWith (*) x y)
Run Code Online (Sandbox Code Playgroud)

你可以\x -> f (g x)用函数组合转换为f . g:

dot x = sum . zipWith (*) x
Run Code Online (Sandbox Code Playgroud)

f . g意思是(.) f g:

dot x = (sum.) (zipWith (*) x)
Run Code Online (Sandbox Code Playgroud)

并且您可以\x -> f (g x)使用函数组合转换为f . g:

dot = (sum.) . zipWith (*)
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个`(f.).g`idiom是用2参数组成1参数函数的常用无点方法,它也可以写成`fmap sum.zipWith(*)`甚至`fmap sum <$> zipWith(*)`我觉得它比`(.)`的​​部分应用更具描述性,因为`( - >)`functor中的`fmap`是等价的对于组合,它通过忽略参数(每个参数一个`fmap`)来说明你在函数结果上"映射"的事实. (3认同)