【问题标题】:Cant figure out what type signature I need for this simple interest function无法弄清楚这个简单的兴趣函数需要什么类型的签名
【发布时间】:2020-09-21 19:14:23
【问题描述】:

所以我试图制作一个递归的单利函数,但我终其一生都无法弄清楚我需要使用什么类型的签名。这是我的代码:

interest :: (Fractional a) => a-> a-> a-> a
interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1)

这段代码给了我错误“无法推断 (Eq a) 从文字 '0' 从上下文:小数a 受类型签名的约束: 兴趣 :: forall a.小数 a => a -> a -> a -> a "

但是当我尝试将约束更改为 (Eq a) 时,它告诉我“可能修复 (Fractional a)

有人可以帮帮我吗?

【问题讨论】:

  • 同时使用两个限制? (顺便说一句,它们实际上被称为“约束”)
  • 是的,将其固定为约束。还有你说的同时使用是什么意思?像这样的东西(Eq a,小数 a)?

标签: haskell


【解决方案1】:

在第一个子句中对0 的检查要求a 也是Eq 类型类的一个实例,因此您应该将其添加到签名中:

interest :: (Eq a, Fractional a) => a-> a -> a -> a
interest p r 0 = p
interest p r t = (1 + (p/100))*interest p r (t-1)

【讨论】:

    【解决方案2】:

    值得一提的是,你可以通过这个“小技巧”找出类型,不要手动告诉类型,当你这样卡住时让 Haskell 为你思考:

    interest p r 0 = p
    interest p r t = (1 + (p/100))*interest p r (t-1) 
    

    这样,代码编译就好了,然后去终端就行了:

    :t interest
    interest :: (Eq t1, Fractional t2, Num t1) => t2 -> t3 -> t1 -> t2
    

    如果您替换字母并删除额外的类型类 Num(因为在您的情况下您需要 Fractional 实例),它与 Willem 的答案完全相同:

    t1 ==> 一个; t2 ==> 一个; t3 ==> 一个

    interest :: (Eq a, Fractional a) => a -> a -> a -> a
    

    但最好想想,你真正需要什么类型的,为什么?

    【讨论】:

    • 这确实有时很有用——但 IMO 仅用于泛化、更改或简化类型签名:您有已经工作的代码,但签名是单态的,您希望使其多态,或者更改某些依赖项它的签名和你想要适应,或者你有多余的约束。另一方面,对于 new 代码,认为没有签名的原型设计更快是一个常见的初学者谬误。
    • @leftaroundabout 确实,应该用来给你一些提示,还是好好想想吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多