Haskell:根据条件将列表细分为更小的组
Haskell: subdividing a list into smaller groups based on a condition
当我们给函数一个条件和一个列表时,它应该将元素分组到一个列表中,直到一个不满足条件。然后它应该创建一个新的子列表,直到再次满足条件,依此类推。
示例:
切片甚至 [1,3,2,4,5,7,4,6] == [[],[1,3],[2,4],[5,7],[4 ,6]]
slice :: (a -> Bool) -> [a] -> [[a]]
slice _ [] = [[]]
slice a (x:y:xs)
| (a x == True && a y == True) || (a x == False && a y == False) = [(x : y : slice a xs)]
| a x == True && a y == False = [x] : [y : slice a xs]
| a x == False && a y == True = [x] : [y : slice a xs]
当我尝试编译您的代码时,出现错误:
main.hs:4:80: error:
* Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a]
Actual type: [[a]]
* In the second argument of `(:)', namely `slice a xs'
In the second argument of `(:)', namely `y : slice a xs'
In the expression: (x : y : slice a xs)
* Relevant bindings include
xs :: [a] (bound at main.hs:3:14)
y :: a (bound at main.hs:3:12)
x :: a (bound at main.hs:3:10)
a :: a -> Bool (bound at main.hs:3:7)
slice :: (a -> Bool) -> [a] -> [[a]] (bound at main.hs:2:1)
|
4 | | (a x == True && a y == True) || (a x == False && a y == False) = [(x : y : slice a xs)]
| ^^^^^^^^^^
exit status 1
例如,您不能执行4:[[6]]
。所以我创建了一个允许这样做的函数myadd :: a -> [[a]] -> [[a]]
。
为了消除更多错误,我使用了对运算符 :
的透彻了解。
第一次启动尝试后,我被迫添加了一个额外的退出规则:slice _ [y] = [[y]]
.
你设计和修改的结果函数没有return想要的结果。
有必要将其修改为 return 所需的输出。
slice :: (a -> Bool) -> [a] -> [[a]]
slice _ [] = [[]]
slice _ [y] = [[y]]
slice a (x:y:xs)
| (a x == True && a y == True) || (a x == False && a y == False) = myadd x (slice a (y:xs))
| a x == True && a y == False = [x] : slice a (y:xs)
| a x == False && a y == True = [x] : slice a (y:xs)
输出:
[[1,3],[2,4],[5,7],[4,6]]
我会按如下方式解决任务:
slice :: (a -> Bool) -> [a] -> [[a]]
slice a b = slice' a b False
slice' :: (a -> Bool) -> [a] -> Bool -> [[a]]
slice' _ [] _ = [[]]
slice' a (x:xs) b
| a x == b = []:(slice' a (x:xs) (not b))
| otherwise = myadd x (slice' a xs b)
输入:
[1,3,2,4,5,7,4,6]
输出:
[[],[1,3],[2,4],[5,7],[4,6]]
附录:
myadd a (x:xs) = (a:x):xs
当我们给函数一个条件和一个列表时,它应该将元素分组到一个列表中,直到一个不满足条件。然后它应该创建一个新的子列表,直到再次满足条件,依此类推。
示例:
切片甚至 [1,3,2,4,5,7,4,6] == [[],[1,3],[2,4],[5,7],[4 ,6]]
slice :: (a -> Bool) -> [a] -> [[a]]
slice _ [] = [[]]
slice a (x:y:xs)
| (a x == True && a y == True) || (a x == False && a y == False) = [(x : y : slice a xs)]
| a x == True && a y == False = [x] : [y : slice a xs]
| a x == False && a y == True = [x] : [y : slice a xs]
当我尝试编译您的代码时,出现错误:
main.hs:4:80: error:
* Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [a]
Actual type: [[a]]
* In the second argument of `(:)', namely `slice a xs'
In the second argument of `(:)', namely `y : slice a xs'
In the expression: (x : y : slice a xs)
* Relevant bindings include
xs :: [a] (bound at main.hs:3:14)
y :: a (bound at main.hs:3:12)
x :: a (bound at main.hs:3:10)
a :: a -> Bool (bound at main.hs:3:7)
slice :: (a -> Bool) -> [a] -> [[a]] (bound at main.hs:2:1)
|
4 | | (a x == True && a y == True) || (a x == False && a y == False) = [(x : y : slice a xs)]
| ^^^^^^^^^^
exit status 1
例如,您不能执行4:[[6]]
。所以我创建了一个允许这样做的函数myadd :: a -> [[a]] -> [[a]]
。
为了消除更多错误,我使用了对运算符 :
的透彻了解。
第一次启动尝试后,我被迫添加了一个额外的退出规则:slice _ [y] = [[y]]
.
你设计和修改的结果函数没有return想要的结果。 有必要将其修改为 return 所需的输出。
slice :: (a -> Bool) -> [a] -> [[a]]
slice _ [] = [[]]
slice _ [y] = [[y]]
slice a (x:y:xs)
| (a x == True && a y == True) || (a x == False && a y == False) = myadd x (slice a (y:xs))
| a x == True && a y == False = [x] : slice a (y:xs)
| a x == False && a y == True = [x] : slice a (y:xs)
输出:
[[1,3],[2,4],[5,7],[4,6]]
我会按如下方式解决任务:
slice :: (a -> Bool) -> [a] -> [[a]]
slice a b = slice' a b False
slice' :: (a -> Bool) -> [a] -> Bool -> [[a]]
slice' _ [] _ = [[]]
slice' a (x:xs) b
| a x == b = []:(slice' a (x:xs) (not b))
| otherwise = myadd x (slice' a xs b)
输入:
[1,3,2,4,5,7,4,6]
输出:
[[],[1,3],[2,4],[5,7],[4,6]]
附录:
myadd a (x:xs) = (a:x):xs