Dan*_*ema 0 import haskell either binary-decision-diagram newtype
我在 haskell 程序中使用决策图库。为此,我想声明 2 种不同的(新)类型来跟踪我正在处理的决策图。我使用的库是 cudd,决策图基类型有一个 DdNode,但我的问题仅与 Haskell 相关。
newtype Bdd = ToBdd Cudd.Cudd.DdNode
newtype Zdd = ToZdd Cudd.Cudd.DdNode
Run Code Online (Sandbox Code Playgroud)
通常我想在调用函数时区分它们,但现在我想使用一个不必区分这两种类型的函数。我主要尝试通过 3 种不同的方式来解决这个问题:
data Dd = ToBdd Bdd | ToZdd Zdd
printDdInfo :: Dd -> IO()
printDdInfo (ToZdd dd) = do
putStrLn "Hello, zdd!"
Cudd.Cudd.cuddPrintDdInfo manager dd
printDdInfo (ToBdd dd) = do
putStrLn "Hello, bdd!"
Cudd.Cudd.cuddPrintDdInfo manager dd
printDdInfo :: Either Bdd Zdd -> IO()
printDdInfo (ToZdd dd) = do
putStrLn "Hello, zdd!"
Cudd.Cudd.cuddPrintDdInfo manager dd
printDdInfo (ToBdd dd) = do
putStrLn "Hello, bdd!"
Cudd.Cudd.cuddPrintDdInfo manager dd
printDdInfo :: Either Bdd Zdd -> IO()
printDdInfo dd = case dd of
Zdd dd -> do
putStrLn "Hello, bdd!"
Cudd.Cudd.cuddPrintDdInfo manager dd
Bdd dd -> do
putStrLn "Hello, bdd!"
Cudd.Cudd.cuddPrintDdInfo manager dd
Run Code Online (Sandbox Code Playgroud)
所有这些方法都失败了。编写这段代码最优雅的方式是什么?感谢您的关注。
我没有深入研究你的代码,但从你的描述来看,你可能对幻影类型的想法感兴趣。
newtype Dd x = ToDd (Cudd.Cudd.DdNode)
data B
data Z
Run Code Online (Sandbox Code Playgroud)
现在,您可以区分何时需要Dd B和Dd Z何时需要,并Dd x在您不关心时进行多态处理。
在现代 GHC Haskell 中,如果你想表明BandZ是唯一的标签,你可以使用DataKindsandKindSignatures扩展并这样做:
newtype Dd (x :: DdTag) = ToDd (Cudd.Cudd.DdNode)
data DdTag = B | Z
Run Code Online (Sandbox Code Playgroud)
在此上下文中,您将处理Dd 'Band Dd 'Z,其中单引号(发音为“tick”)将数据构造函数“提升”到类型级别。
要编写一个根据类型所具有的标签而行为不同的函数,您需要一个类。
class Zoop tag where
zoop :: Dd tag -> Int
zeep :: Char -> Dd tag
zaaaaap :: Dd tag -> Dd tag
Run Code Online (Sandbox Code Playgroud)
现在,你可以写一个Zoop,例如B(或'B正向)和一个Z(或'Z)让用户使用方法的那么多。但是请记住,这些类型在编译时会被擦除,因此您在Zoop a任何时候想要将这些方法与多态标签一起应用时都需要一个约束。
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |