为什么这不会加载到GHCI

时间:2016-07-20 12:44:49

标签: haskell

我不明白为什么这不会加载到交互式Haskell解释器中。当我直接在GHCI中输入函数定义时,它的效果非常好。但是当我尝试从.hs文件加载函数定义时,就是当我收到错误消息时。有任何想法吗?谢谢你的帮助。

let partialsums lst = reverse ( partial_sums lst 0 [] ) where
                      partial_sums ls accum accumulator_list = 
                      if ls == [] then accumulator_list else
                      partial_sums ( tail ls ) ( accum + head ls ) 
                      ((accum + head ls) : accumulator_list)

我在Python,Ruby和Ocaml中尝试过相同的函数定义。没问题! (Python的空白规则简单直观.Ruby和Ocaml不读取空格。在这些语言中,空格严格用于方便阅读程序的人。但我认为Haskell有一些非常严格的空白规则,我不熟悉与。)

感谢您的帮助。 Haskell肯定看起来很有趣,但如果没有好教授的监督或指导,这是一种难以学习的语言。我只是想自己学习这门语言。

2 个答案:

答案 0 :(得分:5)

这不是空白 - 它是let(并且你必须缩进partial_sums的身体,因为chi提到了 - 抱歉我最初没有检查过这一点:

如果你想在.hs文件中定义函数,你应该写这样的东西:

partialsums lst = reverse ( partial_sums lst 0 [] ) where
                  partial_sums ls accum accumulator_list = 
                     if ls == [] then accumulator_list else
                     partial_sums ( tail ls ) ( accum + head ls ) 
                     ((accum + head ls) : accumulator_list)

虽然我会写得更像这样:

partialsums lst = reverse ( partial_sums lst 0 [] ) 
   where
      partial_sums ls accum accumulator_list = 
         if ls == [] 
         then accumulator_list 
         else
            partial_sums ( tail ls ) ( accum + head ls ) 
                  ((accum + head ls) : accumulator_list)

改善它

我还建议添加签名并使用模式匹配代替ifheadtail,如下所示:

partialsums :: Num a => [a] -> [a]
partialsums lst = reverse ( partial_sums lst 0 [] ) 
   where
      partial_sums [] _ accumulator_list = accumulator_list
      partial_sums (h:tl) accum accumulator_list =
            let accum' = accum + h in
            partial_sums tl accum' (accum' : accumulator_list)

所有人都应该给你:

> partialsums [1..5]
[1,3,6,10,15]

使用scanl1

有趣的事实:您实际上可以使用scanl1来定义这一点非常简单:

partialSums :: Num a => [a] -> [a]
partialSums = scanl1 (+)

答案 1 :(得分:0)

感谢您的答案!什么时候适合使用" let"关键词?是的,这正是我无法将我的功能定义加载到GHCI的原因。

我也在玩Python。 Python的列表推导非常棒。在Python中,partialsums函数可以这样写:

def partialsums(array):    返回[sum([array [n] for n in range(0,t + 1)])for t in range(0,len(array))]

我知道Haskell也使用列表推导,但对于Haskell,语法有点不同。关于如何在Haskell中做类似事情的任何想法?谢谢您的帮助! (别担心。这不适合上课。我只是想自己弄清楚Haskell。我想我会尝试一下。这是一种有趣的语言,但绝对具有挑战性。)