从两个列表中删除 'a' 和 'A' 字符,并将它们 return 作为一对
Remove the 'a' and 'A' characters from two lists and return them as a pair
Implement the filterA2 :: [Char] -> [Char] -> ([Char], [Char])
function that removes the characters 'a'
and 'A'
from both of the lists and returns the results as a pair.
For example:
filterA2 "Always" "runAway" == ("lwys", "runwy")
filterA2 "Cherry" "Tree" == ("Cherry", "Tree")
到目前为止,我已经尝试过:
filterA2 [] [] = ([], [])
filterA2 ['a'] ['a'] = ([], [])
filterA2 ['A'] ['A'] = ([], [])
filterA2 ['a'] [xs] = ([], [xs])
filterA2 [xs] ['a'] = ([xs], [])
filterA2 ['A'] [xs] = ([], [xs])
filterA2 [xs] ['A'] = ([xs], [])
filterA2 (x:xs) (y:ys) = filterA2 (xs) (ys)
无论我输入什么,总是 returns ("", "")
。我可能使用了太多基本案例。
你的方法的问题是:你的模式只有在每个列表中只有一个字符时才有效...
filterA2 :: [Char] -> [Char] -> ([Char], [Char])
filterA2 l1 l2 = (remove l1, remove l2)
where
remove :: [Char] -> [Char]
remove [] = []
remove (x:xs)
|x == 'A' || x == 'a' = remove xs
| otherwise = x : remove xs
import Data.Char (toLower)
filterA2 :: [Char] -> [Char] -> ([Char], [Char])
filterA2 [] [] = ([], [])
filterA2 (x:xs) []
| toLower x == 'a' = (xs', [])
| otherwise = (x:xs', []) where
(xs', _) = filterA2 xs []
filterA2 [] (y:ys)
| toLower y == 'a' = ([], ys')
| otherwise = ([], y:ys') where
(_, ys') = filterA2 [] ys
filterA2 (x:xs) (y:ys)
| toLower x == 'a' && toLower y == 'a' = (xs', ys')
| toLower x == 'a' = (xs', y:ys')
| toLower y == 'a' = (x:xs', ys)
| otherwise = (x:xs', y:ys') where
(xs', ys') = filterA2 xs ys
如果您需要使用显式递归和模式匹配来完成,以上是使用这些方法来完成的方法。当然,使用内置函数会使代码更易于实现和更易于阅读,但您这样做可能是出于教育目的。
如您所见,有 4 种基本模式,每种模式都有特定的案例,根据模式实现为守卫。关键思想是每个函数 return 一个由递归函数调用 return 编辑的 2 个值的元组。
filterA2 (x:xs) (y:ys) = (x:xs', y:ys') where
(xs', ys') = filterA2 xs ys
抛开警卫和不同的案例,看看我们如何创建元组。因此,撇开 haskell 的惰性不谈,即使代码想在每个瞬间尽可能多地计算,它也无法计算函数的 return 值,除非它有 return 来自栈下递归调用的值。因此,结果是该函数沿着递归堆栈向下移动,直到它到达底部,因为两个列表都已为空,因此基本情况模式匹配:
filterA2 [] [] = ([], [])
此时最低的函数return是它的值,然后它上面的函数也可以计算return它的值,以此类推,直到最后的结果是returned.
Implement the
filterA2 :: [Char] -> [Char] -> ([Char], [Char])
function that removes the characters'a'
and'A'
from both of the lists and returns the results as a pair.For example:
filterA2 "Always" "runAway" == ("lwys", "runwy")
filterA2 "Cherry" "Tree" == ("Cherry", "Tree")
到目前为止,我已经尝试过:
filterA2 [] [] = ([], [])
filterA2 ['a'] ['a'] = ([], [])
filterA2 ['A'] ['A'] = ([], [])
filterA2 ['a'] [xs] = ([], [xs])
filterA2 [xs] ['a'] = ([xs], [])
filterA2 ['A'] [xs] = ([], [xs])
filterA2 [xs] ['A'] = ([xs], [])
filterA2 (x:xs) (y:ys) = filterA2 (xs) (ys)
无论我输入什么,总是 returns ("", "")
。我可能使用了太多基本案例。
你的方法的问题是:你的模式只有在每个列表中只有一个字符时才有效...
filterA2 :: [Char] -> [Char] -> ([Char], [Char])
filterA2 l1 l2 = (remove l1, remove l2)
where
remove :: [Char] -> [Char]
remove [] = []
remove (x:xs)
|x == 'A' || x == 'a' = remove xs
| otherwise = x : remove xs
import Data.Char (toLower)
filterA2 :: [Char] -> [Char] -> ([Char], [Char])
filterA2 [] [] = ([], [])
filterA2 (x:xs) []
| toLower x == 'a' = (xs', [])
| otherwise = (x:xs', []) where
(xs', _) = filterA2 xs []
filterA2 [] (y:ys)
| toLower y == 'a' = ([], ys')
| otherwise = ([], y:ys') where
(_, ys') = filterA2 [] ys
filterA2 (x:xs) (y:ys)
| toLower x == 'a' && toLower y == 'a' = (xs', ys')
| toLower x == 'a' = (xs', y:ys')
| toLower y == 'a' = (x:xs', ys)
| otherwise = (x:xs', y:ys') where
(xs', ys') = filterA2 xs ys
如果您需要使用显式递归和模式匹配来完成,以上是使用这些方法来完成的方法。当然,使用内置函数会使代码更易于实现和更易于阅读,但您这样做可能是出于教育目的。
如您所见,有 4 种基本模式,每种模式都有特定的案例,根据模式实现为守卫。关键思想是每个函数 return 一个由递归函数调用 return 编辑的 2 个值的元组。
filterA2 (x:xs) (y:ys) = (x:xs', y:ys') where
(xs', ys') = filterA2 xs ys
抛开警卫和不同的案例,看看我们如何创建元组。因此,撇开 haskell 的惰性不谈,即使代码想在每个瞬间尽可能多地计算,它也无法计算函数的 return 值,除非它有 return 来自栈下递归调用的值。因此,结果是该函数沿着递归堆栈向下移动,直到它到达底部,因为两个列表都已为空,因此基本情况模式匹配:
filterA2 [] [] = ([], [])
此时最低的函数return是它的值,然后它上面的函数也可以计算return它的值,以此类推,直到最后的结果是returned.