我正在学习Haskell的函数式编程,我有这个练习,其中我有[a], z
,[a]
任何类型的列表和z
我要删除的元素[a]
z
1}}。这个问题有点容易解决(即使是像Haskell这样的新手),但我遇到了打印输出所需的麻烦。
我需要创建一个元组,其中第一个元素是没有任何z
元素的列表,以及它在a
内找到[2,3,4,2,2] 2
的次数}。几个例子:
([3,4],3)
输出:[1,1,1,1] 1
输入:([],4)
输出:[1,2,3,4] 5
输入:([1,2,3,4],0)
ex3 :: (Eq a, Num a) => [a] -> a -> ([a],Int)
ex3 [] _ = ([],0)
ex3 (x:xs) z | x == z = (xs,1) -- this line is wrong, but idk how to fix it
| otherwise = ([0],0) -- same here
到目前为止,我已经完成了类似的事情,但我不知道如何继续前进:
z
我已单独完成这两个问题(删除z
元素并计算[a]
中z
的次数。看起来像这样:
a)删除ex3a :: (Eq a) => [a] -> a -> [a]
ex3a [] _ = []
ex3a (x:xs) z | x == z = ex3a xs z
| otherwise = x : ex3a xs z
元素:
z
b)计算[a]
中ex3b :: (Eq a) => [a] -> a -> Int
ex3b [] _ = 0
ex3b (x:xs) z | x == z = 1 + ex3b xs z
| otherwise = ex3b xs z
的次数:
$result
答案 0 :(得分:5)
通常,你会想到像归纳定义这样的数学函数。例如,函数的第一行可以是:
“空列表的ex3
,任何元素都是包含空列表的零元素,而”
ex3 [] _ = ([], 0)
对于非空列表,当然问题有点困难。就像你的代码一样,这里基本上有两种情况。
“非空列表的ex3
和列表首部 等于z
的元素z
是与列表的尾的ex3
相同,但前面加上该列表的头部“,所以我们可以这样写:
ex3 [] _ = ([], 0)
ex3 (x:xs) z | x /= z = (x:t, n)
| otherwise = ...
where (t, n) = ex3 xs z
所以在这里我们使用列表ex3
的尾部对xs
进行递归调用,然后我们获得结果元组(t, n)
,因此t
包含“已擦除” “尾部,n
我们删除元素的次数,如果是x /= z
,那么我们可以返回(x:t, n)
,因为删除的数量不会改变,但我们必须将x
添加到列表中。
“非空列表的ex3
和列表头部等于z
的元素z
与{{1}相同列表的尾,但递增计数“,所以:
ex3
然后我们获得预期的结果:
ex3 :: (Eq a, Num n) => [a] -> a -> ([a], n)
ex3 [] _ = ([], 0)
ex3 (x:xs) z | x /= z = (x:t, n)
| otherwise = (t, n+1)
where (t, n) = ex3 xs z
答案 1 :(得分:3)
为了好玩,这就是我实现该功能的方式:
var b = []byte(`{"a": "str", "A": 123}`)
type TMP struct {
// A interface{} `json:"a"`
a string `json:"a"`
A int `json:"A"`
}
我喜欢的是递归模式是显而易见的 - 至少对那些熟悉Haskell标准库的人来说 - 没有仔细审查(因为它只是对import Data.Foldable
import Data.Monoid
ex3 :: Eq a => [a] -> a -> ([a], Int)
ex3 haystack needle = getSum <$> foldMap inject haystack where
inject hay | hay == needle = ([], 1)
| otherwise = ([hay], 0)
的调用)
答案 2 :(得分:0)
分区函数使用谓词和列表;它产生一对列表,其第一个元素满足谓词,第二个元素不满足。
import Data.List (partition)
ex4 :: Eq a => [a] -> a -> ([a], Int)
ex4 xs x = length <$> partition (/= x) xs