首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Haskell中两项构造函数比较的一般方法

Haskell中两项构造函数比较的一般方法
EN

Stack Overflow用户
提问于 2017-12-18 03:09:30
回答 2查看 318关注 0票数 4

给定某些数据类型的两个术语t1 t2,是否有方法检查t1和t2是否以相同的构造函数开始,而不对构造函数进行彻底的情况或模式匹配?如果我的类型要么是b,那我就想

代码语言:javascript
复制
checkConst (Left x) (Left y) = True
checkConst (Right x) (Left y) = False
...

以此类推,而不是真正地进行模式匹配,并且在一种方式上可以推广到其他类型,并有10个构造函数的顺序。有什么好办法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-18 03:36:34

您可能正在寻找Data.Data模块中可用的泛型功能。如果使用派生的Data实例定义数据类型,如下所示:

代码语言:javascript
复制
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
data Foo = Bar1 Int
         | Bar2 String String
         | Bar3 Double
         deriving (Data)

然后可以使用toConstr检索值的构造函数。

代码语言:javascript
复制
> toConstr (Bar1 1)
Bar1
> toConstr (Bar2 "hello" "there")
Bar2
>

这些值是Constr类型的值,可以比较它们是否相等,因此您可以定义:

代码语言:javascript
复制
checkConst :: (Data g) => g -> g -> Bool
checkConst x y = toConstr x == toConstr y

并得到:

代码语言:javascript
复制
> checkConst (Bar1 10) (Bar1 20)
True
> checkConst (Bar1 10) (Bar3 20)
False
>
票数 6
EN

Stack Overflow用户

发布于 2017-12-18 03:27:01

您可以使用某种中间类型,它可以唯一地区分每个构造函数并具有一个Eq实例。例如,您可以使用Int来区分每个数据构造函数,然后比较这些值。

代码语言:javascript
复制
checkConst x y = toInt x == toInt y
  where
    toInt (Left _)  = 1 :: Int
    toInt (Right _) = 2

如果您的类型从Data实现Data.Data,则可以使用toConstr作为中间类型使用Constr。在Either的情况下,这是不必要的,因为您可以使用isRight x == isRight y,但是对于具有10个构造函数的数据类型,这将更加简洁。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47861648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档