简体   繁体   English

Haskell中的模式匹配列表

[英]Pattern matching in haskell for lists

[Noob question] I have a list in haskell with only two elements : [noob问题]我在haskell中有一个只有两个元素的列表:

mylist = ["Apple", "Mango"]

When I try to do pattern matching like this 当我尝试像这样进行模式匹配时

[firstelemet ,secondelement] = mylist;

I get this kind of warning. 我得到这种警告。

warning: [-Wincomplete-uni-patterns] Pattern match(es) are non-exhaustive In a pattern binding: Patterns not matched: [] [ ] ( : : :_) 警告:[-Wincomplete-UNI-图案]模式匹配(ES)都是非穷举的在图案结合:模式不匹配:[] [](:::_)

Any suggestions on how this can be done in a better way. 关于如何更好地完成此操作的任何建议。 Actually I need to do this for unit testing that returns a list with two elements. 实际上,对于返回包含两个元素的列表的单元测试,我需要这样做。

When teaching people to unit test in ML-based languages, I often get the question on how to verify a monadic value. 当教人们使用基于ML的语言进行单元测试时,我经常会遇到一个问题,即如何验证一元数值。 Is that what's you're trying to do here? 那是你想在这里做什么吗?

The question is often a variation on: 问题通常是:

How do I get the value out of the monad? 我如何从monad中获得价值?

My answer is typically: 我的答案通常是:

You don't. 你不知道 You step into the monad. 您踏入单子。

Are you trying to do something like this? 您是否正在尝试做这样的事情?

assertEquals "Apple" firstelement
assertEquals "Mango" secondelement

Here, I'm assuming that you have some sort of assertEquals function... 在这里,我假设您有某种assertEquals函数...

If so, it helps to realise that Haskell lists are Eq when elements are Eq , so instead, you could just write something like this: 如果是这样,它有助于认识到Haskell的列表是Eq ,当元素是Eq ,所以相反,你可以只写是这样的:

assertEquals ["Apple", "Mango"] mylist

If that doesn't work for you, you could introduce a little helper function like this: 如果那对您不起作用,则可以引入一些辅助功能,如下所示:

tryPair :: [a] -> Maybe (a, a)
tryPair [x, y] = Just (x, y)
tryPair _      = Nothing

This would enable you to first do this: 这将使您能够首先执行以下操作:

m = tryPair mylist

Maybe a is also Eq if a is Eq , so you could write your assertion like this: 如果aEqMaybe a也是Eq ,因此您可以这样编写断言:

assertEquals (Just ("Apple", "Mango")) m

If this still doesn't work for you, perhaps you could write a test utility function like this: 如果这仍然不适合您,也许您可​​以编写如下的测试实用程序函数:

assertJust :: Maybe a -> (a -> ()) -> ()
assertJust (Just x) f = f x
assertJust Nothing _ = assertFail "Boo! Nothing!"

This would enable you to write something like this: 这将使您能够编写如下内容:

assertJust (tryPair mylist) $ \(x, y) -> assertEquals "Apple" x

You can write this as 你可以这样写

mylist = ["Apple", "Mango"]
firstelement : secondelement : _ = mylist

to get the exact thing that you want, though the other approaches suggested here are probably better, conceptually. 从概念上讲,尽管这里建议的其他方法可能更好,但可以得到所需的确切东西。 Note that this will only work with lists of at least 2 elements. 请注意,这仅适用于至少包含2个元素的列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM