我是Haskell的新手,我正试图弄清楚如何添加而不必使用'+'符号。我正在使用Winhugs作为编译器。
让我们说, cookies = 10,巧克力= 5,蛋糕= 20
如果我进入,
cookies 1 chocolate 1
输出应该是,
15
这就是我所拥有的
cookies :: Int -> Int
cookies 1 = 10
cookies n = 10 + cookies (n-1)
chocolate :: Int -> Int
chocolate 1 = 5
chocolate n = 5 + chocolate (n-1)
我必须进入,
cookies 1 + chocolate 1
为了得到15.还有另一种方法吗?
我也试过使用递归类型,但我仍然觉得它很混乱。我也尝试了这个,但我只能添加两个项目,我总是要输入cookie:
cookies :: Int -> (Int -> Int) -> Int -> Int
cookies x item y = (x * 20) + item y
cake :: Int -> Int
cake 1 = 20
cake n = 20 + cake (n-1)
chocolate :: Int -> Int
chocolate 1 = 5
chocolate n = 5 + chocolate (n-1)
另外,我不能只输入cookie,因为它应该总是有另一个项目。
cookies 1
错误 - 无法找到“显示”功能:
***表达:cookies 1
***类型:(Int - > Int) - > Int - > INT
我很抱歉这个非常棒的问题。谢谢所有可以提供帮助的人!
**更新** 我知道我可以使用不同的编译器,但它是在学校教授的内容,它也是我们需要用于我们项目的编译器:(
答案 0 :(得分:6)
我不明白为什么你想要这一切。您尝试实施的内容称为variadic function。 Haskell并不真正支持这些,我真的不相信将它们用于您的应用程序是有意义的。 cookies 1 + chocolate 2
出了什么问题?
也就是说,Haskell2010 / GHC-Haskell类型系统足够灵活,可以将各种可变功能混合在一起:
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class Crumbles c where
crumble :: Int -> c
instance Crumbles Int where
crumble = id
instance (f ~ (Int -> Int), i ~ Int, Crumbles c) => Crumbles (f -> i -> c) where
crumble acc f i = crumble $ f i + acc
现在你可以做到
cookies :: Crumbles c => Int -> c
cookies n = crumble $ n*10
chocolate :: Crumbles c => Int -> c
chocolate n = crumble $ n*5
goodies :: [Int]
goodies = [ cookies 1 -- 10
, cookies 1 chocolate 1 -- 15
, cookies 1 chocolate 1 cookies 100000 -- 1000015
]
main :: IO ()
main = print goodies
......给予[10,15,1000015]
。
我不知道Hugs是否支持等式约束TypeFamilies
和f ~ (Int -> Int)
所需的i ~ Int
扩展名。
我怀疑任务的用途是完全不同的,即如何实现 cookies :: Int -> Int
而不使用加法或乘法,即不写*10
也10 + cookies (n-1)
。他们可能想要的答案应该只使用succ
和pred
函数(分别相当于+1
和-1
)。
答案 1 :(得分:2)
不要尝试编写名为cookies
和chocolate
的函数,这些函数在输入hugs解释器时会表现得那样。
相反,尝试编写一个IO
动作,接受输入,解析它,并进行适当的计算。您可能喜欢interact
函数,该函数在String
上执行函数并在用户键入的内容上运行它:
interact :: (String -> String) -> IO ()
例如,使用runhaskell(与拥抱非常相似),代码如下:
main = interact $ \s ->
"What is your name?\n" ++
filter (/='\n') s ++ ", nice to meet you!\n"
产生以下互动:
% runhaskell test.hs
What is your name?
Daniel
Daniel, nice to meet you!
请注意,我在输入Daniel
并按回车键后按下了EOF按钮;在Linux上这是ctrl-d但我相信在Windows上它是ctrl-z。另请注意,代码中没有Daniel
的定义 - 我输入的Daniel
是而不是一个Haskell术语,而是通过运行Haskell术语main
。
答案 2 :(得分:1)
cookies
和chocolate
。相反,它可能要求函数calculate :: String -> Int
接受字符串 "cookies 1 chocolate 2"
,解析它,并返回结果。
为此,解决方案非常简单 - 所以我不会放弃它。将问题分解为以下小步骤:
"cookies 1 chocolate 2"
["cookies", "1", "chocolate", "2"]
[("cookies", 1), ("chocolate", 2)]
[10, 10]
20
为每个步骤编写一个函数,并为要求输入的main
编写函数并调用这些函数来计算最终结果。如果您考虑如何使用Maybe
或Either
来处理输入中的错误,例如未知项目,非数字数量,缺失数量和& c。