我需要更改列表例如:
[1,2,4,6,5,10]
到这个
[1,2,5]
(位置正确的元素列表)。
等。如何解决下面附带的错误?
我的代码:
module Count where
import Control.Monad.State
nthel n xs = last xsxs
where xsxs = take n xs
deleteNth i items = take i items ++ drop (1 + i) items
repeatNTimes 0 _ = return ()
repeatNTimes n xs =
do
if (n == nthel n xs) then return()
else deleteNth (n-1) xs
repeatNTimes (n-1) xs
list = [1,2,3,4,5]
main = repeatNTimes (length list) list
我有以下错误:
* Couldn't match type `Int' with `()'
Expected type: [()]
Actual type: [Int]
* In the expression: deleteNth (n - 2) xs
In a stmt of a 'do' block:
if (n == nthel n xs) then return () else deleteNth (n - 2) xs
In the expression:
do { if (n == nthel n xs) then return () else deleteNth (n - 2) xs;
repeatNTimes (n - 1) xs }
答案 0 :(得分:2)
使用它的一个非常好的方法是将功能拼接在一起。首先,您可能需要了解Data.List
模块中的功能,您可以使用hoogle找到这些功能:http://hoogle.haskell.org
Data.List模块功能
我会在这里给你一点提升。我要选择的函数是zip
函数:https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-List.html#v:zip,其类型为[a] -> [b] -> [(a, b)]
,然后是filter
函数https://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:filter,其类型为(a -> Bool) -> [a] -> [a]
然后是类型为map
的{{1}}函数以及(a -> b) -> [a] -> [b]
功能组合
这些函数可以使用函数组合运算符拼接在一起:fst :: (a, b) -> a
它需要两个共享公共输入/输出点的函数(在类型签名中它们分别是第二个和第一个参数; {{1然后它会将它们连接成一个单独的函数。
(.) :: (b -> c) -> (a -> b) -> a -> c
)然后将它们连接成一个函数。
堆叠起来 - 需要知识
为了做你想做的事情,你真的需要知道简单类型,参数化类型,范围(包括惰性无限范围会有所帮助),函数和可能的递归以及一些高阶函数以及Haskell函数是如何咖喱,并了解功能组成。添加对类型组合做什么和做什么的基本理解并没有什么坏处。
我帮助创作了一个教程,通过遵循一系列有趣的例子,这些教程可以帮助我们从使用的角度理解这些东西是如何工作的。它不会太长,一旦你理解了一些更基础的东西,你可能会发现更容易解决你的问题:http://happylearnhaskelltutorial.com - 请注意,它并没有调整教你如何构建东西,这将是以后的卷,但它应该给你足够的理解,能够至少猜到一个答案,或理解下面的答案。
答案 - 剧透
如果你想自己解决这个问题,你应该停在这里,稍后当你感到更自信时回来。但是,我将在下面提出一个可能的答案,所以不要看你是否还想知道!
a -> b
请记住,这只是实现此目的的一种方式。有更简单的解释方法,虽然它可能看起来效率低下,但Haskell有 list / stream fusion ,它将该函数编译成可以对数据进行单次传递的内容。