【问题标题】:Type Constraints in Data Declaration Haskell数据声明 Haskell 中的类型约束
【发布时间】:2017-04-11 02:06:26
【问题描述】:

我正在使用 Haskell 并尝试编写以下内容:

data Scale s = Scale s s

但是,我想让s 必须是 Num 类型类的东西,例如 Int 或 Double。使用 Haskell 和 GHC 可以做到吗?

【问题讨论】:

  • 这是可能的,但几乎绝不是您应该做的。将Num s 约束只放在实际需要它的函数上通常要好得多。
  • Alec,我所有使用 scale 的函数都需要 num 约束。
  • @AviCaspe 有很好的理由不这样做。答案包含一个,但还有其他。你真的应该考虑把约束放在需要的地方。

标签: haskell types typeclass


【解决方案1】:

是的:

{-# LANGUAGE GADTs #-}
data Scale s where
    Scale :: Num s => s -> s -> Scale s

但是,通常认为最佳做法这样做。相反,仅将Num 约束放在使用Scales 并且需要 Num 约束的函数上。对这些约束放宽允许你在适当的地方暂时打破不变量;例如通常希望这种类型有一个 Functor 实例,如果你像上面那样约束构造函数,这是不可能的。

【讨论】:

    【解决方案2】:

    Point 类型我也遇到过类似的情况。但是我没有考虑约束,我考虑了如何概括我的观点的元素类型。然后我明白如果我有像data Point a = Point a a 这样的点类型,那么我可以做 Functor、Applicative、Foldable 和 Traversable 的实例。我可以通过标准的通用方式设计功能。例如:

    dist :: Floating a => Point a -> Point a -> a
    dist a b = sqrt $ sum $ (^2) <$> ((-) <$> a <*> b)
    

    我有疑问。到底是怎么回事? :) 如果我添加约束(如您所问),我将无法通过这种方式进行设计,我需要实现很多功能,例如 pointSub

    所以,有一些事情要考虑:)

    【讨论】:

    • 确实,您甚至可以为such a type 制作一个Monad instance
    • 是的,我知道,你是对的。但我觉得这个例子并不有趣:)
    【解决方案3】:

    这个呢:

    data Scale' s = Scale s s
    type Scale = Scale' Int Int
    

    我没有尝试过,我不太了解 Haskell,只是(大部分)阅读过它,但这似乎是合理的,不是吗? ?

    【讨论】:

    • 这当然是合理的,但它与 OP 所要求的完全不同。
    • 我认为它解决了隐藏在问题背后的主要问题。
    猜你喜欢
    • 2012-09-28
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多