模式匹配monadic结果?

时间:2011-08-24 19:50:03

标签: haskell monads

我正在学习Haskell并希望使用“readHex”,根据Hoogle的类型:

readHex :: Num a => ReadS a

如何从这样的功能中“提取”结果?什么是最常见的方式,模式匹配正确的构造函数,即[(a,“”)] ??

一般来说,LiftM和提升似乎有些意义,但是当涉及“解开”monadic堆栈时,我迷失了。

4 个答案:

答案 0 :(得分:7)

为了回答一般性问题,从数据构造函数中提取值的 only 方式是模式匹配。某些数据类型带有为您提取值的函数,但这些函数本身是通过模式匹配实现的,或者调用其他函数,即& c。想要隐藏其内部结构的抽象数据类型(如Data.Map.MapIO)仍需要模式匹配才能使用;不同之处在于它们不会从定义它们的模块中导出它们的构造函数,因此您需要处理的是模块中定义的其他函数及其提供的操作。

要回答具体问题,请ReadS is defined

type ReadS a = String -> [(a, String)]

所以它只是一个类型的同义词。您不需要从ReadS本身提取任何内容,它只是简写或别名。实际类型为[(a, String)],您可以像使用列表,元组,String等其他任何方式一样工作。

此外,ReadS不是Monad。它是不是Monad实例的类型的同义词,实际上不能直接组成一个(没有办法以实例声明所需的形式编写[(a, String)])。

答案 1 :(得分:2)

这里没有任何monadic。 ReadS只是一种类型别名(link)。

如果您执行:

> readHex "41A"

然后你会得到一个元组的单例列表:

[(1050,"")]

有很多方法可以提取值1050。有些人会使用case语句。我将使用listToMaybe

定义辅助功能
readHexToVal :: Num a => String -> Maybe a
readHexToVal = listToMaybe . map fst . readHex

答案 2 :(得分:2)

ReadS a类型只是String -> [(a, String)]的同义词。这是一个接受一个输入字符串并给出匹配列表的函数 - 第一个元素是结果值,第二个元素是匹配的字符串。在你的情况下,很可能只有一个匹配,所以我建议你这样使用它:

case readHex str of
  ((num,""):_) -> ...
  _            -> error ...

答案 3 :(得分:0)

您可以使用let:

取出结果
let ((d, _):_) = readHex "123ab"