我正在学习Haskell并希望使用“readHex”,根据Hoogle的类型:
readHex :: Num a => ReadS a
如何从这样的功能中“提取”结果?什么是最常见的方式,模式匹配正确的构造函数,即[(a,“”)] ??
一般来说,LiftM和提升似乎有些意义,但是当涉及“解开”monadic堆栈时,我迷失了。
答案 0 :(得分:7)
为了回答一般性问题,从数据构造函数中提取值的 only 方式是模式匹配。某些数据类型带有为您提取值的函数,但这些函数本身是通过模式匹配实现的,或者调用其他函数,即& c。想要隐藏其内部结构的抽象数据类型(如Data.Map.Map
或IO
)仍需要模式匹配才能使用;不同之处在于它们不会从定义它们的模块中导出它们的构造函数,因此您需要处理的是模块中定义的其他函数及其提供的操作。
要回答具体问题,请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"