Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching against monadic result?

Tags:

haskell

monads

I am learning Haskell and want to use "readHex", which according to Hoogle has type:

readHex :: Num a => ReadS a

How do you "extract" a result from such a function? What's the most common way, pattern match against the right constructor ie, [(a,"")] ??

LiftM and lifting in general seems to make some sense, but I'm lost when it comes to "unwinding" the monadic stack.

like image 525
overscore Avatar asked Oct 18 '25 12:10

overscore


2 Answers

To answer the general question in general terms, the only way to extract values from a data constructor is pattern matching. Some data types come with functions that extract values for you, but those functions are themselves implemented with pattern matching, or call other functions that are, &c. Abstract data types like Data.Map.Map or IO, that want to hide their internal structure, still require pattern matching to work with; the difference is that they don't export their constructors from the module that defines them, so all you have to work with are other functions defined in the module and the operations they provide.

To answer the specific question, ReadS is defined as such:

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

So it's just a type synonym. You don't need to extract anything from the ReadS itself, it's just a shorthand or alias. The actual type is [(a, String)], which you can work with the same way you would anything else using lists, tuples, Strings, and so on.

Furthermore, ReadS is not a Monad. It's a type synonym for something that isn't a Monad instance, and in fact can't be made into one directly (there's no way to write [(a, String)] in the form required for an instance declaration).

like image 142
C. A. McCann Avatar answered Oct 20 '25 01:10

C. A. McCann


There's nothing monadic here. ReadS is simply a type alias (link).

If you execute:

> readHex "41A"

Then you will get a singleton list of a tuple:

[(1050,"")]

There are numerous ways to extract the value 1050. Some would use a case statement. I would define an auxilary function using listToMaybe:

readHexToVal :: Num a => String -> Maybe a
readHexToVal = listToMaybe . map fst . readHex
like image 39
Thomas M. DuBuisson Avatar answered Oct 20 '25 02:10

Thomas M. DuBuisson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!