我是Haskell的新手,我正在尝试编写简单的函数让自己习惯于语法,我想编写自己的函数,将某个元素添加到特定索引的列表中。这是我在Atom(我的文本编辑器)中写的:
addElem :: a->[a]->Int->[a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = a ++ (elem:b) where a = take index list; b = drop index list
| otherwise = list
这个想法是,只要索引是Int
并且elem
与list
的元素属于同一类型,它就不会吓到,但是当我尝试加载到ghci我得到“|''的解析错误。”我是否需要约束参数的类型?我正在阅读Learn You A Haskell,但我还没有完全解释缩进的工作原理,所以我的错误也可能就在那里。
答案 0 :(得分:11)
where
块需要在整个函数结束时发生,并在所有情况下共享。您可能打算使用let
:
addElem :: a -> [a] -> Int -> [a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = let a = take index list; b = drop index list in a ++ (elem:b)
| otherwise = list
另请注意,let
可以更简洁地编写为let (a,b) = splitAt index list in ...
。 splitAt
也在序曲中。当然,您也可以将where
块移动到函数的末尾(Haskell的懒惰使得这很容易理解)。
addElem :: a -> [a] -> Int -> [a]
addElem elem list index
| index <= 0 = elem:list
| index < (length list) = a ++ (elem:b)
| otherwise = list
where
a = take index list
b = drop index list
就个人而言,我更喜欢这个,因为它表明a
和b
可以在函数的其他地方使用。
2010 Haskell Report的第4.4.3节详细介绍了允许where
的位置。