Haskell中的数学函数是否有特定类型?

时间:2019-01-16 14:44:02

标签: function haskell types

我想编写一个带有数学函数(/,x,+,-)的函数,一个以数字开头的数字,以及一个数字列表。然后,应该返回一个列表。

第一个元素是起始编号,第二个元素是起始编号的值加/减/乘以给定列表的第一个数字。第三个元素是前一个结果的结果加上/减去/时间/除以给定列表的第二个结果,依此类推。

如果我告诉代码要使用哪个函数,我将使所有工作正常,但是如果我想让用户输入他想要的数学函数,则类型有问题。例如,尝试:t(/)会给出modalDraggableClickOutside('#modal-example', 'iframeLoaded', 'Modal shown'); ,但是如果将其放在类型的开头,则会失败。

是否存在区分这些功能的特定类型(/,x,+,-)?还是有另一种成功编写此函数的方法?

Fractional a => a -> a -> a

正确的解决方案是这样的:

prefix :: (Fractional a, Num a) => a -> a -> a -> a -> [a] -> [a]

prefix (f) a b = [a] ++ prefix' (f) a b


prefix' :: (Fractional a, Num a) => a -> a -> a -> a -> [a] -> [a]

prefix' (z) x [] = []

prefix' (z) x y = [x z (head y)] ++ prefix' (z) (head (prefix' (z) x y)) (tail y)

2 个答案:

答案 0 :(得分:3)

  

是否存在区分这些功能的特定类型(/*+-)?

我看不出这样做的理由。为什么\x y -> x+y被认为比\x y -> x + y + 1更好。确保将两个数字相加是大多数人认为更“纯”的事情。但是将自己限制为特定的功能子集很奇怪。对于某些功能\x y -> f x y - 1“发生”等于(+)的情况,也有可能出现,除了编译器无法确定。

类型检查将确保如果给定列表包含字符串等,则不能传递对数字进行操作的函数。但是,有意地进一步限制它不是很有用。为什么要阻止程序员将函数用于不同目的?

  

还是有另一种方法可以成功编写此函数?

您在这里描述的是scanl :: (b -> a -> b) -> b -> [a] -> [b]函数。如果我们用scanl调用scanl f z [x1, x2, ..., xn],那么我们将获得一个列表[z, f z x1, f (f z x1) x2, ...]scanl可以定义为:

scanl :: (b -> a -> b) -> b -> [a] -> [b]
scanl f = go
    where go z [] = [z]
          go z (x:xs) = z : go (f z x) xs

因此,我们首先发出 accumulator (从初始值开始),然后使用旧的f z x,{ {1}}列表的开头,然后递归到列表的末尾。

答案 1 :(得分:2)

如果要限制这四个操作,只需自己定义类型:

data ArithOp = Plus | Minus | Times | Div

as_fun Plus = (+)
as_fun Minus = (-)
as_fun Times = (*)
as_fun Div = (/)