我想创建一个在String
类型列表中查找[(String, Int)]
的函数,并返回与Int
配对的String
。
像这样:
λ> assignmentVariable "x" [("x", 3), ("y", 4), ("z", 1)]
3
以下是我尝试的内容:
assignmentVariable :: String -> [(String, Int)] -> Int
assignmentVariable [] = error "list is empty"
assignmentVariable n (x:xs) = if x == n
then xs
else assignmentVariable
我怎么写这个?
答案 0 :(得分:7)
让我们来看看发布的代码:
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable [] = error "list is empty"
assignmentVariable n (x:xs) = if x == n then xs else ...
第一个等式只有一个参数,而第二个等式有两个。让我们解决这个问题。
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n (x:xs) = if x == n then xs else ...
由于我们执行x == n
,因此这些变量必须属于同一类型。
但是,n::String
和x::(String,Integer)
。我们需要在比较之前将x
拆分为其组件。
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n ((m,x):xs) = if m == n then xs else ...
结果xs
是一个列表,而不是类型签名所暗示的Integer
。你只想要x
。
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n ((m,x):xs) = if m == n then x else ...
最后,递归调用。在m/=n
时,我们想要尝试列表xs
中的其他对,所以:
assignmentVariable::String -> [(String, Integer)] -> Integer
assignmentVariable _ [] = error "list is empty"
assignmentVariable n ((m,x):xs) = if m == n
then x
else assignmentVariable n xs
答案 1 :(得分:2)
您希望在对上进行模式匹配。
assignmentVariable expected ((key, value) : rest)
如果变量名称与预期名称匹配,则该对的第一个元素......
= if key == expected
返回关联值,即该对的第二个元素。
then value
否则,您尝试在列表的其余部分中找到该值。
else assignmentVariable expected rest
您可以在没有模式匹配的情况下实现它,当然:
assignmentVariable expected list
= if expected == fst (head list)
then snd (head list)
else assignmentVariable expected (tail list)
但是,这不是Haskell代码中的常用样式。
此功能也存在于Prelude中,名称为lookup
。
答案 2 :(得分:1)
实际上,你已到了一半!
首先,最好是制作更通用的类型签名,以及更好的名称:
myLookup :: (Eq a) => a -> [(a, b)] -> b
你已经完成了[]
的边缘情况的整理,但你还没有完成:
myLookup _ [] = error "myLookup: empty list."
myLookup n ((x, b):xs) = if x == n
then b
else myLookup n xs
你的问题就是你在else
之后的问题:你没有递归调用函数,你返回的函数没有任何意义 - 你需要用不同的参数再次调用它复发。
如果您想进行改进,请尝试为类型Eq a => a -> [(a, b)] -> Maybe b
创建类似的功能以进行挑战。