function - 如何在 Haskell 中对我的自定义数据类型使用预定义函数(例如 ==、tail)?
问题描述
我是haskell的新手,我在网上读到的任何东西都没有真正帮助我。我的任务是实现一个类型类VEC,它有一个函数factor,如果用户输入的不是两个数字而是两个向量类型的整数列表,它要么计算两个整数的乘法,要么执行两个矩阵的点积。我的代码如下所示:
data Vector = VECTOR [Int] deriving (Show, Eq)
class VEC a where
factor :: a -> a -> a
instance VEC Int where
factor a b = a*b
instance VEC Vector where
factor xs [] = 0
factor xs ys = (head xs) * (head ys) + factor (tail xs) (tail ys)
我假设 Vectors 是类型[Int]
,但现在我不太确定,因为在尝试使用 Hugs 编译代码时收到以下错误消息:
Hugs> :l kdp
ERROR file:kdp.hs:7 - Type error in instance member binding
*** Term : []
*** Type : [a]
*** Does not match : Vector
所以我的问题是:第一行实际上是什么意思?它是与作业一起给出的,我已经看到了许多类似的数据类型定义,但没有一个具有这种特定模式。然后如何解决无法使用预定义函数的问题,例如tail
在上述错误情况下将整数列表与我的自定义数据类型进行比较?我的猜测是我必须自己定义操作,但我不知道该怎么做。
解决方案
当您为类似的类编写实例时
class C a where
method :: a -> a
您将所有参数外观 ( a
) 替换为您正在为其编写实例的类型。例如在你的情况下:
{-# LANGUAGE InstanceSigs #-}
instance VEC Vector where
factor :: Vector -> Vector -> Vector
factor _ _ = undefined
因此,您不能将类型参数Vector
与模式匹配,[]
也不能在其上使用head
或tail
函数,因为它们正在处理列表。但是,您Vector
包含列表,因此您可以简单地解压缩它:
instance VEC Vector where
factor _ (Vector []) = Vector [0] -- you need to return Vector as well
factor (Vector xs) (Vector ys) =
let Vector [x] = factor (Vector $ tail xs) (Vector $ tail ys)
in Vector [(head xs) * (head ys) + x]
这是非常丑陋和局部的,你可以使用一些内置Data.List
的机器让它更性感:
instance VEC Vector where
factor (Vector xs) (Vector ys) =
Vector [sum (zipWith (*) xs ys)]
当您使用deriving (Show, Eq)
时,==
操作员应该可以正常工作。
推荐阅读
- r - 基于符号排名的Quantstrat中的头寸规模?
- java - Java:无法使用 Angular 5 将包含文件类型输入的表单发送到 REST 后端(Spring Boot)
- laravel - 未定义偏移量:更新时为 1(laravel 中的summernote)
- angular - 如何获取本地脚本本地存储中的所有密钥
- node.js - 难以处理 CSV 文件,浏览器超时
- php - 来自数据库的图像不加载 PHP PDO
- ruby-on-rails - Ruby on Rails - erb 模板文件中的条件表着色
- html - 使用css的悬停效果闪烁
- python-3.x - _tkinter.TclError:无法调用“按钮”命令:应用程序已被销毁
- php - 在换行符之后或之前删除三个点