我是否必须为每种新数据类型定义一个函数?

sda*_*das 2 haskell types linear-algebra

我正在使用Haskell并声明了Vectoras

data Vector = Vector [Double]
Run Code Online (Sandbox Code Playgroud)

现在,我想声明dot两个向量的乘积

dot :: Vector -> Vector -> Double
dot a b = sum $ a * b -- I already wrote Vector as an instance of Num for *.
Run Code Online (Sandbox Code Playgroud)

但是,问题是,我收到错误

Couldn't match expected type [a0] with actual type Vector
Run Code Online (Sandbox Code Playgroud)

我认为这意味着sum不知道如何操作Vector.解决此问题的最佳方法是什么?

Dan*_*zer 6

所以我注意到你没有使用标准向量.我建议改用它们,但如果你真的不想,

 toList :: Vector -> [Double]
 toList (Vector a) = a
Run Code Online (Sandbox Code Playgroud)

并使用

dot a b = sum . toList $ a * b
Run Code Online (Sandbox Code Playgroud)

如果切换到标准向量,则有3种选择

  1. 把你Vector变成一个清单,

    import Data.Vector as V
    dot a b = sum . V.toList $ a * b
    
    Run Code Online (Sandbox Code Playgroud)

    简单,但不必要地慢.

  2. 使用更一般 sum

    import Data.Foldable as F
    dot a b = F.sum $ a * b
    
    Run Code Online (Sandbox Code Playgroud)

    灵活,可能会导致奇怪的类型错误,因为我们依赖于另一个类型类.

  3. 使用不同的,具体的(花哨的单词是单态的) sum

     import Data.Vector as V
     dot a b = V.sum $ a * b
    
    Run Code Online (Sandbox Code Playgroud)

    最简单,但当然,如果你停止使用矢量,这将打破.

我建议选项3,不需要过于笼统.