【问题标题】:Haskell rigid type? [duplicate]Haskell 刚性类型? [复制]
【发布时间】:2011-03-12 04:05:26
【问题描述】:

可能重复:
Return specific type within Haskell

这段代码:

class Alpha a where
    half :: Real f => a -> f

instance Alpha Double where
    half a = a/2.0

产生这个错误:

rigid.hs:6:13:
    Couldn't match expected type `f' against inferred type `Double'
      `f' is a rigid type variable bound by
          the type signature for `half' at rigid.hs:3:17
    In the expression: a / 2.0
    In the definition of `half': half a = a / 2.0
    In the instance declaration for `Alpha Double'
Failed, modules loaded: none.

为什么?

编辑:弄清楚刚性类型的业务,我想我已经找到了一个更集中的问题。如何将 Double 转换为满足 Ord 和 Num 的值?也就是说,一个让我(Ord a, Num a) => Double -> a的函数?

【问题讨论】:

  • (fromRational . toRational) :: (Fractional a, Real b) => a -> b 怎么样?
  • ony: 你的类型倒退了; (fromRational . toRational) :: (Real a, Fractional b) => a -> b。这也称为realToFrac

标签: haskell types double


【解决方案1】:

您声称half 可以将a 类型转换为任何Real 类型。但是您的half 只能将a (Double) 转换为Double

【讨论】:

  • 如何执行以下操作:(Ord a, Num a) => Double -> a?
【解决方案2】:

也就是得到我的函数 (Ord a, Num a) => Double -> a?

问题是,你想从中得到什么语义?语义并不总是由类型决定,即使在 Haskell 中也是如此。

此类函数的一个示例(即使没有Ord a 约束)是:

doubleToNum = fromInteger . round

它满足你想要的类型,但是例如如果你应用它来获取Double,它不会给你身份。

【讨论】:

  • 我想我想要这个身份。也许我想的类型都错了?
【解决方案3】:

您将无法找到很多有趣的功能 将Double 转换为OrdNumany 实例。你可以 创建一些满足这两个约束的非常狂野的类型。

在不知道其他任何事情的情况下,构建价值的唯一方法 凭空使用fromInteger。而Ord 实例不是 据我所知,会帮助你。

所以你可以这样做:

f :: (Ord a, Num a) => Double -> a
f = fromInteger . floor

或者更琐碎,f = const 0。 :) 但是你没有多少 可以处理Doubles 的小数部分,因为有 不能保证您的目标类型有任何分数 它。

也许您正在寻找Fractional a => Double -> a? 然后你可以使用realToFrac

【讨论】:

  • 当目标类型不是小数时,您可能想要做的是截断(或舍入),但如果目标类型支持,则保留小数部分。如果是这样,那么您需要使用“多参数类型类”或“关联类型”之类的扩展,使目标类型成为类中变化的一部分。或者只是分别处理这两种情况,每一种都有自己的类。
【解决方案4】:

停止!

深呼吸,写下你“真正”想要的是什么。

我将停止尝试猜测您会喜欢的内容,并要求再次改写。我认为realToFrac 可能会满足您的需求,但我不确定。

您是否正在寻找一个接受 Double 的函数,并且以某种方式“发明”了一个新类型,它是 Ord 和 Num 的成员,但没有更多指定的行为?您想要一种将 Double 与您已经想到的其他类型一起使用的方法吗?

就像一个小型的“思想实验”,想象一下计算机尝试在 Bool 上使用您的函数 - 您能否以某种方式表达问题,使其在 Bool 上有意义,或者它显然无法与布尔?

很抱歉,我无法按要求回答您的问题,但希望我能帮助您以某种方式获得更好的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多