gaa*_*kam 1 constructor haskell types
我有一个(非常复杂的)数据类型:
data SomeDataType = Constructor Blah Blah Blah | OtherConstructor Blah Yadda | YetAnotherConstructor Yadda Yadda Tittle | StillOneMoreConstructor Tittle Tattle Wish Wash
Run Code Online (Sandbox Code Playgroud)
现在,我发现自己想要另一种数据类型…具有两个构造函数。之一将是相同YetAnotherConstructor
的SomeDataType
; 另一个只会存储一个Double
。我有什么选择?
data WantedDataType = ConstructorName1 Double | ConstructorName2 SomeDataType
Run Code Online (Sandbox Code Playgroud)
虽然这可行,但也可以允许ConstructorName2 $ StillOneMoreConstructor tittle tattle wish wash
没有意义的东西。
data WantedDataType = ConstructorName1 Double | ConstructorName2 Yadda Yadda Tittle
Run Code Online (Sandbox Code Playgroud)
再说一次,这是可行的,但在我看来,这违反了DRY的规定,将东西往返于WantedDataType
和转换可能很乏味SomeDataType
。
data WantedDataType = ConstructorName1 Double | YetAnotherConstructor Yadda Yadda Tittle
Run Code Online (Sandbox Code Playgroud)
这就是我最想要的,但是不幸的是,Haskell似乎并不支持这种多态性(构造函数不能同时属于两种数据类型)。
我有什么选择?我该如何解决?
这使我认为YetAnotherConstructor
实际上是“应该”为其自己的数据类型:
data YetAnotherData = YetAnotherConstructor Yadda Yadda Tittle
data SomeDataType = Constructor Blah Blah Blah
| OtherConstructor Blah Yadda
| SomeYetAnotherConstructor {-!-}YetAnotherData
-- ! will make this EXACTLY isomorphic to the original
-- but is likely unnecessary
| StillOneMoreConstructor Tittle Tattle Wish Wash
data WantedDataType = ConstructorName1 Double
| ConstructorName2 {-!-}YetAnotherData
Run Code Online (Sandbox Code Playgroud)
如果您不喜欢说SomeYetAnotherConstructor (YetAnotherConstructor _ _ _)
和ConstructorName2 (YetAnotherData _ _ _)
,则对此有一个扩展(尽管我认为您会认为它使您回到第一个平方):
{-# LANGUAGE PatternSynonyms #-}
pattern SomeYetAnother :: Yadda -> Yadda -> Tittle -> SomeDataType
pattern SomeYetAnother x y z = SomeYetAnotherConstructor (YetAnotherConstructor x y z)
{-# COMPLETE Constructor, OtherConstructor, SomeYetAnother, StillOneMoreConstructor #-}
pattern WantedYetAnother :: Yadda -> Yadda -> Tittle -> WantedDataType
pattern WantedYetAnother x y z = ConstructorName2 (YetAnotherConstructor x y z)
{-# COMPLETE ConstructorName1, WantedYetAnother #-}
Run Code Online (Sandbox Code Playgroud)
这将使数据构造器发挥作用,SomeYetAnother
并WantedYetAnother
像数据构造器一样工作(完成覆盖率检查(COMPLETE
编译指示),模式匹配和构造)。当您不关心它YetAnotherData
是自己的单元时,可以使用它们在每种类型上进行构造/匹配,如果要将“ 单元” 视为一个单元,则可以使用基础SomeYetAnotherConstructor
和ConstructorName2
构造函数YetAnotherData
。后者可能对例如
someToWantedByYet :: SomeDataType -> Maybe WantedDataType
someToWantedByYet (SomeYetAnotherConstructor y) = Just $ ConstructorName2 y
someToWantedByYet _ = Nothing
wantedToSomeByYet :: WantedDataType -> Maybe SomeDataType
wantedToSomeByYet (ConstructorName2 y) = Just $ SomeYetAnotherConstructor y
wantedToSomeByYet _ = Nothing
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
83 次 |
最近记录: |