haskell - 在 Haskell 中调度联合类型
问题描述
我正在尝试在 Haskell 中编写一个基于 String 或 Num 参数的多态函数。
我写了一些无法编译的伪代码:
numDigits strOrNum =
if isString strOrNum then length strOrNum
else isNum strOrNum then length (show strOrNum)
numDigits 1000 -- Should return 4
numDigits "1000" -- Should return 4
请注意isString
,isNum
它们不是真正的 Haskell 函数,它们仅用于演示。
来自 Lisp,strOrNum 是一个联合类型,这个代码可以运行。
我知道 Haskell 中的临时多态性需要类型类,但我不确定如何将它拼凑在一起。
解决方案
将某些东西建模为 sum-type 还是 type-class 更好,我认为您只是随着时间的推移而建立的直觉(sum-types 通常是更好的选择)。
但既然你提到
我知道 Haskell 中的临时多态性需要类型类,但我不确定如何将它拼凑在一起。
这是一个有希望的直观解释。
基本理念
基本上,您是说您的代码可以使用多种类型。您应该尝试制定这些类型的共同点——即为什么您接受这些类型但拒绝其他类型。然后,您定义一个类型类来捕获这一点,并根据该类型类实现您的大部分代码。
你的例子
在你的例子中说明它。您正在接受数字和字符串(表示数字),因为您说两者都可以表示为数字序列,并且您想要定义一个计算这些数字的函数。那么定义一个类型类来捕获被写为数字序列的能力可能是有意义的。
class IsBase10Positional t where
digits :: t -> [Int]
然后,您将为您的类型定义实例:
instance IsBase10Positional Int where
digits n = D.digits 10 n
instance IsBase10Positional String where
digits chars = digitToInt <$> chars
D.digits
来自http://hackage.haskell.org/package/digits-0.3.1/docs/Data-Digits.html#v:digits
digitToInt
来自https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Char.html#v:digitToInt
numDigits
然后在属于此类型类的所有类型上定义您的函数:
numDigits :: IsBase10Positional a => a -> Int
numDigits x = length (digits x)
结论
通常很难制定类型类应该捕获的常见行为。如果您开始将大量函数添加到类型类本身中,那么您可能无法捕捉到类型共有的正确本质(在您的应用程序的域中)。
推荐阅读
- php - 如何在 Symfony 默认查询生成器中添加列
- javascript - 在 vue-native 中使用 svg 图片
- c# - Entity Framework Core 总是返回 null,除非使用 OrderBy?
- java - HttpServletRequest JSON 参数在 Servlet 中发现空值
- json - 从 JSON 中删除字符
- groovy - 如何以键为变量从地图中获取值?
- python - 如何在 Django 网页中显示 excel 文件
- amazon-ecs - 在 Amazon ECS 上设置 Eclipse che 的步骤
- reactjs - 如何translateX,translateY到某个坐标而不是相对点?
- flutter - 如何从 Android Studio 在桌面上启动 Hello World Flutter?