在函数中包含时,键入算术表达式的歧义

时间:2015-06-12 09:54:24

标签: haskell

我正在GHCi命令行(7.8.3)上编写一个简单的函数

scale_x_datetime(breaks=man.breaks, labels=date_format("%H"), limits = man.lims) 

评估时,会给出有关歧义的错误(底部的错误消息)。

但是,如果我替换这些值,可以很好地评估相同的表达式。

let roundBy b x = (round (x/b)) * b

我的问题是:

在上述情况下,当表达式封装在函数中时,是否有办法使ghci的行为相同?

P.S。 错误消息(作为函数计算时):

Prelude> (round (3/10))*10
0

1 个答案:

答案 0 :(得分:3)

这很棘手,但问题是10中的两个(round (3/10))*10不必是同一类型,但当然b中的let roundBy b x = (round (x/b)) * b λ> :t (round (3/10))*10 (round (3/10))*10 :: Integral a => a 必须是。

这就是为什么:

λ> :t roundBy 10 3
roundBy 10 3 :: (RealFrac a, Integral a) => a

Integral a

和GHCi只是知道如何默认为RealFrac a, Integral a,但显然不适用于let roundBy b b' x = (round (x/b)) * b'

所以要真正表现出你需要的相同

λ> roundBy 10 10 3
0

确实:

let roundBy b x = (round (x/fromIntegral b)) * b

如何解决

我忘了在这里添加如何解决问题 - 我想你真的想要这个:

λ> :t roundBy
roundBy :: (Integral a, Integral a1) => a -> a1 -> a
λ> roundBy 10 3
0

你得到:

rem

顺便说一下:为你的功能提供缩进类型通常是一个好主意;)所以我们可以帮助你更好

另一种方法

从它的外观来看,您可以使用λ> let roundBy b x = x - x `rem` b λ> roundBy 10 3 0 λ> roundBy 10 13 10

稍微简化此功能
phrase.split()
Phrase = ["My", "Name", "Is", "My", "Name", "Is"]