返回列表,其中包含列表中的前两个字符串作为元组

Bob*_*obo 1 string haskell list greedy

我正在编写一个Haskell函数,它接受一个字符串列表并返回一个包含前两个字符串的列表作为结果的元组.因此,示例输出将是:

listtuple ["bride", "zilla", "crazy", "women"] = [("bride", "villa")]
listtuple ["basketball", "football"] = [("basketball", "football")]
Run Code Online (Sandbox Code Playgroud)

我正在考虑接近它的方式如下:

listtuple :: Eq a => [Str a] -> [(Str a, Str a)]
listtuple xs = [(x,y) | x <- xs !! 0, y <- xs !! 1]
Run Code Online (Sandbox Code Playgroud)

基本上我认为我可以只选择列表的第一个和第二个索引中的元素,但我收到错误.这里有什么帮助?

Sat*_*vik 10

答案很简单

listtuple :: [a] -> [(a,a)]
listtuple (x:y:_) = [(x,y)]
listtuple _ = []
Run Code Online (Sandbox Code Playgroud)

由于您的列表将始终包含一个项目或没有项目,因此最好使用Maybe这个目的服务器.

listtuple2 :: [a] -> Maybe (a,a)
listtuple2 (x:y:_) = Just (x,y)
listtuple2 _ = Nothing
Run Code Online (Sandbox Code Playgroud)


Gab*_*lez 7

你可能想做的是:

listtuple xs =
    let x = xs !! 0
        y = xs !! 1
     in (x, y)
Run Code Online (Sandbox Code Playgroud)

请注意,这与您编写的内容不同.原因是您编写的列表理解转换为以下内容:

do x <- xs !! 0  -- Treat the first  element of xs as a list
   y <- xs !! 1  -- Treat the second element of xs as a list
   return (x, y)
Run Code Online (Sandbox Code Playgroud)

这说明了这个问题:当你不是列表时,你正在处理xs !! 0xs !! 1作为列表. xs !! 0只是一个元素,所以如果你想声明它x等于xs !! 0,你使用:

let x = xs !! 0
 in <some expression that uses x>
Run Code Online (Sandbox Code Playgroud)

<-列表中理解语法不这样做同样的事情,我建议你避开列表理解的,直到你明白列表单子是如何工作的,因为编译器将列表解析列表单子.

现在,第二个问题是你使用(!!).你应该避开类似的部分功能,(!!)并专注于使用模式匹配来解决这些问题.做你要求的惯用方法是在前两个元素上进行模式匹配:

listtuple (x:y:_) = (x, y)
Run Code Online (Sandbox Code Playgroud)

...除了在包含少于两个元素的列表上失败.您可以通过将结果存储为a来保护这一点Maybe,其中Just包含成功的结果,并Nothing指示失败:

listtuple :: [a] -> Maybe (a, a)
listtuple (x:y:_) = Just (x, y)
listtuple _       = Nothing
Run Code Online (Sandbox Code Playgroud)