haskell - 如何向 Haskell 中的现有 Type 类添加新函数?
问题描述
我目前正在尝试了解 Haskell 类型类。在创建了下面的简单示例并看到它有效之后......
data MyMaybe a = MyNothing | MyJust a
deriving(Show)
class IncreaseByOne a where
addOne :: a -> a
instance (Num a) => IncreaseByOne (MyMaybe a) where
addOne MyNothing = (MyNothing)
addOne (MyJust x) = (MyJust (x+1))
问我自己:是否可以将函数addOne添加到现有的 Type-Class Num。所以所有的数字都可以使用函数addOne。就像是:
instance IncreaseByOne Num where
addOne x = x+1
解决方案
好吧,您原则上可以编写如下实例
{-# LANGUAGE UndecidableInstances #-}
instance (Num a) => IncreaseByOne a where
addOne x = x+1 -- or `addOne = (+1)`
这-XUndecidableInstances
不是一个真正的问题,但问题是这个实例与您可能想要声明的任何其他实例重叠MyMaybe
,特别是与您的实例重叠。出现问题的原因是原则上没有什么能阻止你也有,也许只是稍后在更下游的模块中,
instance Num a => Num (MyMaybe a) where ...
然后两者都Num a => IncreaseByOne a
适用Num a => IncreaseByOne (MyMaybe a)
。
GHC可以做重叠的实例,但这通常是个坏主意。我建议您改为为所有相关的具体类型写出简短的实例。为了使这个更加简洁,您可以有一个基于以下内容的默认实现Num
:
{-# LANGUAGE DefaultSignatures #-}
class IncreaseByOne a where
addOne :: a -> a
default addOne :: Num a => a -> a
addOne = (+1)
instance (Num a) => IncreaseByOne (MyMaybe a) where
addOne = fmap (+1) -- `MyMaybe` _should_ have a `Functor` instance!
instance IncreaseByOne Int -- note no instance body is needed,
instance IncreaseByOne Integer -- because the default implementation
instance IncreaseByOne Double -- applies
推荐阅读
- linux - NERDTree 在特定文件夹中显示为空白
- javascript - 使用数组方法将项目添加到新数组
- java - 为什么我不能用 Spring 的 @Value 注释注入我的 PoJo 之一?
- python - 用python解析sqs响应
- mysql - 我的 sql 加入已经排序的列 desc/获取最后一个数据
- reactjs - 子组件的 useImperativeHandle 用法,但无法从父组件获取功能
- javascript - Mongoose save() 不更新数据库
- python - 如何打开 replit 上传的图像文件?
- azure - 错误:从 WSL 尝试时不存在名称为“Aks_cluster_name”的上下文
- android - 为什么我的 mapbox 组件(在 Ionic 应用程序中)可以在浏览器/本地主机上运行,但当我将它带到我的 Android 模拟器时却不行?