Ben*_*Ben 5 haskell pattern-synonyms
有没有办法在Haskell中创建相当于创建"构造函数别名"的东西?我认为类似于别名,你可以给类型一个不同的名称,但它仍然以各种方式表现为别名类型.
我的用例是一个系统,我将指定的时间作为我正在建模的某些对象的属性,所以UTCTime.其中一些可能是"可变"时间,这意味着它可能尚未分配时间或它所具有的时间是"可移动的".所以Maybe UTCTime.
但只有部分对象具有可变时间.其他人有固定的时间,系统必须作为一个常数; 当前分配给特定时间的时间变量的处理方式与固定时间不同.现在暗示Either UTCTime (Maybe UTCTime); 它可以是固定时间,也可以是未分配的可变时间.
通用类型似乎非常适合我正在尝试建模的东西,所以使用它们感觉很自然.不过,虽然这是什么明显Either UTCTime (Maybe UTCTime) 是,这不是特别明显这是什么意思,所以一些描述性的特殊情况下的名字就好了.
一个简单的type Timeslot = Either UTCTime (Maybe UTCTime)肯定会清理我的类型签名很多,但这对构造函数没有任何作用.我可以使用类似的东西bound = Just来获取构造值的名称,但不能用于模式匹配.
在另一端,我可以用我想要的任何名称定义一个自定义ADT,但后来我失去了Either和Maybe类型的所有预定义功能.或者更确切地说,我将一直来回应用变换(我认为这并不比使用newtype包装器的情况更糟,只是没有效率保证,但我怀疑这无论如何都会成为瓶颈).我想要理解使用泛型Either和Maybe函数操作我的Timeslot值的代码我需要知道标准构造函数映射到我想要使用的任何方式的方式,转换函数将提供一个方便的编译器强制定义的映射.所以也许这是一个很好的方法.
我很确定我知道Haskell很好地说没有构造函数别名这样的东西,但我很好奇是否有一些我不知道的hack,或者其他一些处理这种情况的好方法.
Dan*_*ner 18
尽管你提到了一些缺点,但我强烈建议你为你的类型创建一个新的ADT; 例如
data TimeVariable = Constant UTCTime | Assigned UTCTime | Unassigned
Run Code Online (Sandbox Code Playgroud)
我提出这些论点:
Unassigned和Right Nothing.现在添加六个月并进行相同的比较.Either和Maybe值一样 - 所以我敢打赌你不会像你想象的那样复制几乎相同数量的代码.虽然您可能正在复制某些代码,但为您的构造函数描述性名称提供相同的可读性和重构原因,为您的函数提供描述性名称是有价值的.Either和我的所有产品都是(,).那太差了.我永远无法记住一笔钱的哪一面意味着哪一件事; 在阅读旧代码时,我不得不经常提醒自己每个值应该是什么样的概念类型(例如Right,不告诉你是否在Right这里使用时间变量的一部分或者是你懒得的其他事情的一部分做一个ADT); 我不得不在精神上扩展类型别名; 从我的痛苦中学习.;-)“模式同义词”可能会合并到 ghc 中:http ://ghc.haskell.org/trac/ghc/ticket/5144 。同时还有 -XViewPatterns,它可以让您编写如下内容:
type Timeslot = Either UTCTime (Maybe UTCTime)
fieldA = either Just (const Nothing)
fieldB = either (const Nothing) id
f (fieldA -> Just time) = ...
f (fieldB -> Just time) = ...
f _ = ...
Run Code Online (Sandbox Code Playgroud)