gpt4 book ai didi

haskell - 如何根据Haskell中的类约束改变函数的行为?

转载 作者:行者123 更新时间:2023-12-02 02:44:01 25 4
gpt4 key购买 nike

我有一个数据类型,它表示与概率配对的值的集合。起初,实现只是使用良好的旧列表,但正如您可以想象的那样,这可能是低效的(例如,我使用树而不是列表来存储有序值)
经过一番研究,我想到了使用 GADT

data Tree a b = Leaf | Node {left::Tree a b, val :: (a, b), right :: Tree a b}

data Prob a where
POrd ::Ord a => Tree a Rational -> Prob a
PEq ::Eq a => [(a, Rational)] -> Prob a
PPlain ::[(a, Rational)] -> Prob a
到目前为止,一切都很好。我现在一直在尝试为我的新数据类型创建一个智能构造函数,
这需要 [(a,Rational)]并取决于 a 的约束, 为 Prob 选择正确的构造函数.基本上:
prob :: [(a, Rational)] -> Prob a
-- chooses the "best" constructor based on the constraints of a
这是可能吗?如果没有,我应该如何设计更好的东西?我错过了什么吗?
谢谢!

最佳答案

无法检查“类 T 中的类型为 C 吗?”形式的检查。在 haskell 。这里的问题是很难对这样的问题做出否定的回答并允许单独编译:T可能在 C在一个模块的范围内,但不在另一个模块的范围内,导致语义相当脆弱。
为了确保一致性,Haskell 只允许要求约束,否则会引发编译时错误。
据我所知,您能做的最好的事情是使用另一个自定义类型类,它会告诉您哪种情况是最好的。例如。

{-# LANGUAGE AllowAmbiguousTypes, TypeApplications, ScopedTypeVariables #-}

data BestConstraint a where
BCOrd :: Ord a => BestConstraint a
BCEq :: Eq a => BestConstraint a
BCNone :: BestConstraint a

class BC a where
bestC :: BestConstraint a

instance BC Int where bestC = BCOrd
-- ... etc.
instance BC a => BC [a] where
bestC = case bestC @a of
BCOrd -> BCOrd
BCEq -> BCEq
BCNone -> BCNone

prob :: forall a . BestConstraint a => [(a, Rational)] -> Prob a
prob xs = case bestC @a of
BCOrd -> POrd .... -- build the tree
BCEq -> PEq xs
BCNone -> PPlain xs
但是,您必须为要使用的任何类型提供一个实例。

关于haskell - 如何根据Haskell中的类约束改变函数的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63821091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com