当前位置: 首页 > 知识库问答 >
问题:

函数中的非穷举模式[Haskell]

慕通
2023-03-14

我必须使函数:: [((String, String), Int)]-

这就是我提出的功能:

neighbours pairs@((x1,x2):xs) inputWord
 | pairs == [] = []
 | fst x1 == inputWord = ((snd x1), x2) : (neighbours xs inputWord)
 | snd x1 == inputWord = ((fst x1), x2) : (neighbours xs inputWord)
 | otherwise = (neighbours xs inputWord)

输出应该是一个元组列表,其中的字符串与元组x1中的inputWord以及整数x2成对出现

问题是我得到了我认为不应该存在的非详尽模式。

我试图替换对 == [] = []xs == [] = []

这使得非穷举模式在列表不为空时消失,但也阻止了函数遍历元组的最后一个元组。

共有2个答案

夏俊杰
2023-03-14

如果您定义一个帮助函数来比较inputWord,那么邻居的定义就变得简单多了:

-- You can use other, more descriptive names instead.
type Foo = ((String, String), Int)
type Bar = (String, Int)

-- If it seems odd that I'm using [Bar] instead of Maybe Bar, see below
myLookup :: String -> Foo -> [Bar]
myLookup s ((s1, s2), i) | s == s1 = [(s2, i)]
                         | s == s2 = [(s1, i)]
                         | otherwise = []

neighbors :: [Foo] -> String -> [Bar]
neighbors [] _ = []
neighbors (x:xs) inputWord = case myLookup inputWord x of
                               []  ->     neighbors xs inputWord
                               [y] -> y : neighbors xs inputWord

可以使用concatMap进一步简化,它只是将应用myLookup inputWord的结果连接到输入的每个元素。

neighbors :: [Foo] -> String -> [Bar]
neighbors xs inputWord = concatMap (myLookup inputWord) xs

考虑到这种模式,我们可以通过使用mapaybayfrom数据中的mapaybaymyLookup切换到使用更严格的mabay-Bar返回类型。可能是而不是concatMap。

import Data.Maybe (mapMaybe)

type Foo = ((String, String), Int)
type Bar = (String, Int)

myLookup :: String -> Foo -> Maybe Bar
myLookup s ((s1, s2), i) | s == s1 = Just (s2, i)
                         | s == s2 = Just (s1, i)
                         | otherwise = Nothing

neighbors :: [Foo] -> String -> [Bar]
neighbors xs inputWord = mapMaybe (myLookup inputWord) xs
费锋
2023-03-14

您指定的唯一模式是:

neighbours pairs@((x1,x2):xs) inputWord

这意味着这只适用于非空列表。实际上,模式((x1,x2):xs)“激发”,因为它与列表的第一个元素(x1,x2)和其余元素的“cons”匹配。

检查pair=[]将永远不会成功,因为模式已经意味着这永远不会是空列表。

我们可以为空列表模式添加一个子句,例如作为要匹配的第一个模式。此外,我们可以通过使用非空列表的(((x11,x12),x2):xs)模式来提高代码的可读性。然后,我们不需要使用fstsnd,但可以直接使用x11x12

neighbours :: Eq a => [((a, a), b)] -> a -> [(a, b)]
neighbours [] _ = []
neighbours pairs@(((x11, x12),x2):xs) inputWord
    | inputWord == x11 = (x11, x2) : tl
    | inputWord == x12 = (x12, x2) : tl
    | otherwise = tl
    where tl = neighbours xs inputWord

例如:

Prelude> neighbours [(('a', 'b'), 1), (('b', 'a'), 2), (('b', 'b'), 3), (('a', 'a'), 4)] 'a'
[('a',1),('a',2),('a',4)]

然而,这个函数有点“不对称”,因为对于元组中的两个元素,它“更喜欢”第一个元素而不是第二个元素。如果两个项目x11x12都等于inputWord,则将它们都生成可能更有意义。

 类似资料:
  • 我使用返回元组的函数。但是当我试图运行这个函数时,它给了我一个例外:函数中的非穷尽模式。

  • 我得到了这个例外,有人知道如何摆脱它吗?' ***例外:hw.hs:(33,1)-(35,53):函数船舶中的非详尽模式' 所有函数都工作正常,除了函数。它可能与元组列表的东西,但我不能弄清楚。下面是代码:

  • 我试图编写函数尾部,它将字符串转换成字符串列表,方式如下: 以下是我的实现: 正如标题所暗示的,这个函数中有一些非详尽的模式。不幸的是,我不明白为什么。 我是哈斯克尔的新手。。。任何帮助都将不胜感激!

  • 我的函数使用一个可能是Int的列表作为参数。如果元素=Nothing,则应打印一个。如果元素是一个Just Int,它将打印数字。我以为我抓住了一个基本情况,但我认为我没有抓住正确的一个。。我得到一个非穷举模式错误。 向正确的方向点头表示感谢!:-)

  • 我有一个函数,它想列出所有。 其中t和d是字符串,y是int,f是字符串,r是int(但不确定f和r是否重要,将进一步解释)。 我得到了非穷举模式的错误,并假设这是因为当列表中只有一个元素时,我没有一个,所以我在其他模式之间添加了这个: 它已编译,但当我调用该函数时,它再次告诉我“非穷举模式”。我正在努力思考我错过了什么模式,我应该在之后添加一个通配符模式来捕获所有内容吗?我不想找人把答案打出来,

  • 所以我有这个函数,当我尝试这样使用它时:mergesortedList[1,1][1,1]会给我一个错误: [1,1***异常:SortFunctions.hs:(86,1)-(91,89):函数合并分类列表中的非穷举模式 我无法找出问题的根源,因为我想我已经涵盖了所有可能的案例。这里会有什么问题?