List 如何创建函数迭代器xs f,其中xs是列表,f是Haskell中的一个函数
我正在尝试编写一个函数List 如何创建函数迭代器xs f,其中xs是列表,f是Haskell中的一个函数,list,haskell,List,Haskell,我正在尝试编写一个函数迭代器,可以用作 迭代器lf,其中l是Int数字的列表,f是一个单参数函数。迭代器函数应检查当f函数应用于列表的第一个元素时,它==列表的第二个元素,依此类推所有元素。当应用f时,如果每个元素都等于前一个元素,则返回true 它应该是这样工作的: iterator [3,4,5] (+1) -> True iterator [2,4,5] (+1) -> False 我试图编写一个函数,它接受列表和f函数,检查列表头和第二个函数的值是否为真,然后在迭代器函数中
迭代器
,可以用作
迭代器lf
,其中l
是Int
数字的列表,f
是一个单参数函数。迭代器
函数应检查当f
函数应用于列表的第一个元素时,它==列表的第二个元素,依此类推所有元素。当应用f
时,如果每个元素都等于前一个元素,则返回true
它应该是这样工作的:
iterator [3,4,5] (+1) -> True
iterator [2,4,5] (+1) -> False
我试图编写一个函数,它接受列表和f函数,检查列表头和第二个函数的值是否为真,然后在迭代器函数中,将该函数映射到列表,但它没有编译,我不知道我的想法是否正确
以下是我最近的一次尝试:
func xs f1
| null xs = False
| ((head xs) f1)==(head(tail xs))=True
| otherwise = False
iterator l f
| null l = False
| map (func l f) l ==True=True
| otherwise = False
这个怎么样:
iterator :: (Eq a) => [a] -> (a -> a) -> Bool
iterator [] _ = error "undefined operation on empty list"
iterator xs f = fst $ foldl foo (True, head xs) (tail xs)
where foo (False, _) b = (False, b)
foo (True, a) b = (b == f a, b)
这个怎么样:
iterator :: (Eq a) => [a] -> (a -> a) -> Bool
iterator [] _ = error "undefined operation on empty list"
iterator xs f = fst $ foldl foo (True, head xs) (tail xs)
where foo (False, _) b = (False, b)
foo (True, a) b = (b == f a, b)
这就是你的意思吗
iterator :: (Eq a) => [a] -> (a -> a) -> Bool
iterator xs f = and . zipWith (==) xs . iterate f . head $ xs
这遵循您的直觉:列表是迭代提供的函数的结果,从列表的head元素开始
我们可以编写iterator xs f=xs==take(length xs)(iterate f$head xs)
,但是使用length
会减少它的在线性。如果我们将==
,获取,长度的定义内联并将它们融合在一起,结果将是我们的与代码融合
测试:
前奏曲>迭代器[3,4,5](+1)
正确
前奏曲>迭代器[2,4,5](+1)
假的
这就是你的意思吗
iterator :: (Eq a) => [a] -> (a -> a) -> Bool
iterator xs f = and . zipWith (==) xs . iterate f . head $ xs
这遵循您的直觉:列表是迭代提供的函数的结果,从列表的head元素开始
我们可以编写iterator xs f=xs==take(length xs)(iterate f$head xs)
,但是使用length
会减少它的在线性。如果我们将==
,获取,长度的定义内联并将它们融合在一起,结果将是我们的与代码融合
测试:
前奏曲>迭代器[3,4,5](+1)
正确
前奏曲>迭代器[2,4,5](+1)
假的
你真正想做的是比较
-- with the list [x1, x2, x3, x4] and function f
[f x1, f x2, f x3]
== [ x2, x3, x4]
因此,对于长度N
的列表,存在N-1
比较。使用Prelude
中的函数很容易解决这个问题。如果您意识到[x2,x3,x4]==tail xs
,并且[f x1,f x2,f x3]==map f(init xs)
。因为我们正在比较每个元素,所以我们可以在这两个列表上使用(=)
执行zipWith,或者我们可以只使用列表的Eq
实例。但是,我更喜欢使用zipWith
,因为它允许我们删除对init
的调用,因为zipWith
将在任一列表中的元素用完时停止。最后一步是和将结果合并在一起,解决方案完成:
iterator :: Eq a => [a] -> (a -> a) -> Bool
iterator xs f = and $ zipWith (==) (map f xs) (tail xs)
你真正想做的是比较
-- with the list [x1, x2, x3, x4] and function f
[f x1, f x2, f x3]
== [ x2, x3, x4]
因此,对于长度N
的列表,存在N-1
比较。使用Prelude
中的函数很容易解决这个问题。如果您意识到[x2,x3,x4]==tail xs
,并且[f x1,f x2,f x3]==map f(init xs)
。因为我们正在比较每个元素,所以我们可以在这两个列表上使用(=)
执行zipWith,或者我们可以只使用列表的Eq
实例。但是,我更喜欢使用zipWith
,因为它允许我们删除对init
的调用,因为zipWith
将在任一列表中的元素用完时停止。最后一步是和将结果合并在一起,解决方案完成:
iterator :: Eq a => [a] -> (a -> a) -> Bool
iterator xs f = and $ zipWith (==) (map f xs) (tail xs)
然后
然后
一些可能有助于使您的问题更清楚的注释:1)函数是iterator
,而不是iterator l f
。2) “单座”是什么意思?你见过一个叫做zipWith的小功能吗?您可以将其实现为迭代器xs f=和$zipWith(=)(map f xs)$tail xs
map(func l f)l==True
没有任何意义。map
的结果是一个列表,而True
是一个Bool
,因此比较这些值是否相等是没有意义的。GHC肯定也在抱怨这个问题,请尝试使用这些错误消息来修复代码。谢谢Bheklillr,我会尝试我认为iterator[].
应该是True
。这既符合数理逻辑,也符合递归定义(你应该理解并使用贝克利尔的优秀定义,而不是这一个):iterator(x:y:ys)f=fx==y&&iterator(y:ys)f
,这意味着基本情况是iterator\uuu=True
。考虑到iterator[a].
应该是正确的,但很简单,iterator[].
也应该是正确的。一些有助于让你的问题更清楚的注释:1)是iterator
是一个函数,而不是iterator l f
。2) “单座”是什么意思?你见过一个叫做zipWith的小功能吗?您可以将其实现为迭代器xs f=和$zipWith(=)(map f xs)$tail xs
map(func l f)l==True
没有任何意义。map
的结果是一个列表,而True
是一个Bool
,因此比较这些值是否相等是没有意义的。GHC肯定也在抱怨这个问题,请尝试使用这些错误消息来修复代码。谢谢Bheklillr,我会尝试我认为iterator[].
应该是True
。这既符合数理逻辑,也符合递归定义(你应该理解并使用贝克利尔的优秀定义,而不是这一个):iterator(x:y:ys)f=fx==y&&iterator(y:ys)f
,这意味着基本情况是iterator\uuu=True
。视为迭代器[a]
应该是真的,但很简单,