Related
Is there a built-in function with signature :: (Monad m) => m a -> a ?
Hoogle tells that there is no such function.
Can you explain why?
A monad only supplies two functions:
return :: Monad m => a -> m a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Both of these return something of type m a, so there is no way to combine these in any way to get a function of type Monad m => m a -> a. To do that, you'll need more than these two functions, so you need to know more about m than that it's a monad.
For example, the Identity monad has runIdentity :: Identity a -> a, and several monads have similar functions, but there is no way to provide it generically. In fact, the inability to "escape" from the monad is essential for monads like IO.
There is probably a better answer than this, but one way to see why you cannot have a type (Monad m) => m a -> a is to consider a null monad:
data Null a = Null
instance Monad Null where
return a = Null
ma >>= f = Null
Now (Monad m) => m a -> a means Null a -> a, ie getting something out of nothing. You can't do that.
This doesn't exist because Monad is a pattern for composition, not a pattern for decomposition. You can always put more pieces together with the interface it defines. It doesn't say a thing about taking anything apart.
Asking why you can't take something out is like asking why Java's Iterator interface doesn't contain a method for adding elements to what it's iterating over. It's just not what the Iterator interface is for.
And your arguments about specific types having a kind of extract function follows in the exact same way. Some particular implementation of Iterator might have an add function. But since it's not what Iterators are for, the presence that method on some particular instance is irrelevant.
And the presence of fromJust is just as irrelevant. It's not part of the behavior Monad is intended to describe. Others have given lots of examples of types where there is no value for extract to work on. But those types still support the intended semantics of Monad. This is important. It means that Monad is a more general interface than you are giving it credit for.
Suppose there was such a function:
extract :: Monad m => m a -> a
Now you could write a "function" like this:
appendLine :: String -> String
appendLine str = str ++ extract getLine
Unless the extract function was guaranteed never to terminate, this would violate referential transparency, because the result of appendLine "foo" would (a) depend on something other than "foo", (b) evaluate to different values when evaluated in different contexts.
Or in simpler words, if there was an actually useful extract operation Haskell would not be purely functional.
Is there a build-in function with signature :: (Monad m) => m a -> a ?
If Hoogle says there isn't...then there probably isn't, assuming your definition of "built in" is "in the base libraries".
Hoogle tells that there is no such function. Can you explain why?
That's easy, because Hoogle didn't find any function in the base libraries that matches that type signature!
More seriously, I suppose you were asking for the monadic explanation. The issues are safety and meaning. (See also my previous thoughts on magicMonadUnwrap :: Monad m => m a -> a)
Suppose I tell you I have a value which has the type [Int]. Since we know that [] is a monad, this is similar to telling you I have a value which has the type Monad m => m Int. So let's suppose you want to get the Int out of that [Int]. Well, which Int do you want? The first one? The last one? What if the value I told you about is actually an empty list? In that case, there isn't even an Int to give you! So for lists, it is unsafe to try and extract a single value willy-nilly like that. Even when it is safe (a non-empty list), you need a list-specific function (for example, head) to clarify what you mean by desiring f :: [Int] -> Int. Hopefully you can intuit from here that the meaning of Monad m => m a -> a is simply not well defined. It could hold multiple meanings for the same monad, or it could mean absolutely nothing at all for some monads, and sometimes, it's just simply not safe.
Because it may make no sense (actually, does make no sense in many instances).
For example, I might define a Parser Monad like this:
data Parser a = Parser (String ->[(a, String)])
Now there is absolutely no sensible default way to get a String out of a Parser String. Actually, there is no way at all to get a String out of this with just the Monad.
There is a useful extract function and some other functions related to this at http://hackage.haskell.org/package/comonad-5.0.4/docs/Control-Comonad.html
It's only defined for some functors/monads and it doesn't necessarily give you the whole answer but rather gives an answer. Thus there will be possible subclasses of comonad that give you intermediate stages of picking the answer where you could control it. Probably related to the possible subclasses of Traversable. I don't know if such things are defined anywhere.
Why hoogle doesn't list this function at all appears to be because the comonad package isn't indexed otherwise I think the Monad constraint would be warned and extract would be in the results for those Monads with a Comonad instance. Perhaps this is because the hoogle parser is incomplete and fails on some lines of code.
My alternative answers:
you can perform a - possibly recursive - case analysis if you've imported the type's constructors
You can slink your code that would use the extracted values into the monad using monad >>= \a -> return $ your code uses a here as an alternative code structure and as long as you can convert the monad to "IO ()" in a way that prints your outputs you're done. This doesn't look like extraction but maths isn't the same as the real world.
Well, technicaly there is unsafePerformIO for the IO monad.
But, as the name itself suggests, this function is evil and you should only use it if you really know what you are doing (and if you have to ask wether you know or not then you don't)
I have a record type say
data Rec {
recNumber :: Int
, recName :: String
-- more fields of various types
}
And I want to write a toString function for Rec :
recToString :: Rec -> String
recToString r = intercalate "\t" $ map ($ r) fields
where fields = [show . recNumber, show . recName]
This works. fields has type [Rec -> String]. But I'm lazy and I would prefer writing
recToString r = intercalate "\t" $ map (\f -> show $ f r) fields
where fields = [recNumber, recName]
But this doesn't work. Intuitively I would say fields has type Show a => [Rec -> a] and this should be ok. But Haskell doesn't allow it.
I'd like to understand what is going on here. Would I be right if I said that in the first case I get a list of functions such that the 2 instances of show are actually not the same function, but Haskell is able to determine which is which at compile time (which is why it's ok).
[show . recNumber, show . recName]
^-- This is show in instance Show Number
^-- This is show in instance Show String
Whereas in the second case, I only have one literal use of show in the code, and that would have to refer to multiple instances, not determined at compile time ?
map (\f -> show $ f r) fields
^-- Must be both instances at the same time
Can someone help me understand this ? And also are there workarounds or type system expansions that allow this ?
The type signature doesn't say what you think it says.
This seems to be a common misunderstanding. Consider the function
foo :: Show a => Rec -> a
People frequently seem to think this means that "foo can return any type that it wants to, so long as that type supports Show". It doesn't.
What it actually means is that foo must be able to return any possible type, because the caller gets to choose what the return type should be.
A few moments' thought will reveal that foo actually cannot exist. There is no way to turn a Rec into any possible type that can ever exist. It can't be done.
People often try to do something like Show a => [a] to mean "a list of mixed types but they all have Show". That obviously doesn't work; this type actually means that the list elements can be any type, but they still have to be all the same.
What you're trying to do seems reasonable enough. Unfortunately, I think your first example is about as close as you can get. You could try using tuples and lenses to get around this. You could try using Template Haskell instead. But unless you've got a hell of a lot of fields, it's probably not even worth the effort.
The type you actually want is not:
Show a => [Rec -> a]
Any type declaration with unbound type variables has an implicit forall. The above is equivalent to:
forall a. Show a => [Rec -> a]
This isn't what you wan't, because the a must be specialized to a single type for the entire list. (By the caller, to any one type they choose, as MathematicalOrchid points out.) Because you want the a of each element in the list to be able to be instantiated differently... what you are actually seeking is an existential type.
[exists a. Show a => Rec -> a]
You are wishing for a form of subtyping that Haskell does not support very well. The above syntax is not supported at all by GHC. You can use newtypes to sort of accomplish this:
{-# LANGUAGE ExistentialQuantification #-}
newtype Showy = forall a. Show a => Showy a
fields :: [Rec -> Showy]
fields = [Showy . recNumber, Showy . recName]
But unfortunatley, that is just as tedious as converting directly to strings, isn't it?
I don't believe that lens is capable of getting around this particular weakness of the Haskell type system:
recToString :: Rec -> String
recToString r = intercalate "\t" $ toListOf (each . to fieldShown) fields
where fields = (recNumber, recName)
fieldShown f = show (f r)
-- error: Couldn't match type Int with [Char]
Suppose the fields do have the same type:
fields = [recNumber, recNumber]
Then it works, and Haskell figures out which show function instance to use at compile time; it doesn't have to look it up dynamically.
If you manually write out show each time, as in your original example, then Haskell can determine the correct instance for each call to show at compile time.
As for existentials... it depends on implementation, but presumably, the compiler cannot determine which instance to use statically, so a dynamic lookup will be used instead.
I'd like to suggest something very simple instead:
recToString r = intercalate "\t" [s recNumber, s recName]
where s f = show (f r)
All the elements of a list in Haskell must have the same type, so a list containing one Int and one String simply cannot exist. It is possible to get around this in GHC using existential types, but you probably shouldn't (this use of existentials is widely considered an anti-pattern, and it doesn't tend to perform terribly well). Another option would be to switch from a list to a tuple, and use some weird stuff from the lens package to map over both parts. It might even work.
From what I understand Foldable basically represents structures that have a number of elements of the same type that can be iterated over, i.e. lists, maps, sets, etc.
Is there a class like Appendable or Insertable which basically represents structures one can add elements to? Of course there would be no guarantee of the order of which elements are retrieved.
I'd rather not create a class myself if there already is one.
You should look at the Data.Collections package. It contains the Unfoldable typeclass with the following methods:
class Unfoldable c i | c -> i where
insert :: i -> c -> c
empty :: c
singleton :: i -> c
It also provides the insertMany and insertManySorted methods, to insert all the elements from a Foldable into an Unfoldable.
If you make your type an instance of both Foldable and Unfoldable then you can both insert and retrieve elements from it.
I think insertion itself isn't really a sensible concept. There are better ways to generalize this. For example Alternative is a sensible type class there. You get pure for singletons and some generic union operation in the form of <|>.
Is there a class like Appendable or Insertable which basically represents structures one can add elements to?
You want to be clearer on what you mean by "add elements." Because there are two ways this could go:
class Insertable c where
-- Add one element to the collection.
insert :: a -> c a -> c a
class Appendable c where
-- Append a collection to another.
append :: c a -> c a -> c a
The latter, you will note, does not support adding a lone a to the collection unless you add an operation like this:
class Pointed c where
singleton :: a -> c a
Note that if you have Appendable and Pointed instances you can define an Insertable:
instance (Appendable c, Pointed c) => Insertable c where
insert x xs = append (singleton x) xs
The Insertable class, together with operations for actually accessing the collection's elements (e.g. the Foldable class), can likewise be used to define an Appendable instance.
In any case, my mock Appendable class above is really just Monoid in disguise. My Insertable can likewise be seen as a disguised version of Chris Taylor's suggested Unfoldable class. I'd go with the Collection class from that package, though, which combines both Unfoldable with Foldable.
Is there a built-in function with signature :: (Monad m) => m a -> a ?
Hoogle tells that there is no such function.
Can you explain why?
A monad only supplies two functions:
return :: Monad m => a -> m a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Both of these return something of type m a, so there is no way to combine these in any way to get a function of type Monad m => m a -> a. To do that, you'll need more than these two functions, so you need to know more about m than that it's a monad.
For example, the Identity monad has runIdentity :: Identity a -> a, and several monads have similar functions, but there is no way to provide it generically. In fact, the inability to "escape" from the monad is essential for monads like IO.
There is probably a better answer than this, but one way to see why you cannot have a type (Monad m) => m a -> a is to consider a null monad:
data Null a = Null
instance Monad Null where
return a = Null
ma >>= f = Null
Now (Monad m) => m a -> a means Null a -> a, ie getting something out of nothing. You can't do that.
This doesn't exist because Monad is a pattern for composition, not a pattern for decomposition. You can always put more pieces together with the interface it defines. It doesn't say a thing about taking anything apart.
Asking why you can't take something out is like asking why Java's Iterator interface doesn't contain a method for adding elements to what it's iterating over. It's just not what the Iterator interface is for.
And your arguments about specific types having a kind of extract function follows in the exact same way. Some particular implementation of Iterator might have an add function. But since it's not what Iterators are for, the presence that method on some particular instance is irrelevant.
And the presence of fromJust is just as irrelevant. It's not part of the behavior Monad is intended to describe. Others have given lots of examples of types where there is no value for extract to work on. But those types still support the intended semantics of Monad. This is important. It means that Monad is a more general interface than you are giving it credit for.
Suppose there was such a function:
extract :: Monad m => m a -> a
Now you could write a "function" like this:
appendLine :: String -> String
appendLine str = str ++ extract getLine
Unless the extract function was guaranteed never to terminate, this would violate referential transparency, because the result of appendLine "foo" would (a) depend on something other than "foo", (b) evaluate to different values when evaluated in different contexts.
Or in simpler words, if there was an actually useful extract operation Haskell would not be purely functional.
Is there a build-in function with signature :: (Monad m) => m a -> a ?
If Hoogle says there isn't...then there probably isn't, assuming your definition of "built in" is "in the base libraries".
Hoogle tells that there is no such function. Can you explain why?
That's easy, because Hoogle didn't find any function in the base libraries that matches that type signature!
More seriously, I suppose you were asking for the monadic explanation. The issues are safety and meaning. (See also my previous thoughts on magicMonadUnwrap :: Monad m => m a -> a)
Suppose I tell you I have a value which has the type [Int]. Since we know that [] is a monad, this is similar to telling you I have a value which has the type Monad m => m Int. So let's suppose you want to get the Int out of that [Int]. Well, which Int do you want? The first one? The last one? What if the value I told you about is actually an empty list? In that case, there isn't even an Int to give you! So for lists, it is unsafe to try and extract a single value willy-nilly like that. Even when it is safe (a non-empty list), you need a list-specific function (for example, head) to clarify what you mean by desiring f :: [Int] -> Int. Hopefully you can intuit from here that the meaning of Monad m => m a -> a is simply not well defined. It could hold multiple meanings for the same monad, or it could mean absolutely nothing at all for some monads, and sometimes, it's just simply not safe.
Because it may make no sense (actually, does make no sense in many instances).
For example, I might define a Parser Monad like this:
data Parser a = Parser (String ->[(a, String)])
Now there is absolutely no sensible default way to get a String out of a Parser String. Actually, there is no way at all to get a String out of this with just the Monad.
There is a useful extract function and some other functions related to this at http://hackage.haskell.org/package/comonad-5.0.4/docs/Control-Comonad.html
It's only defined for some functors/monads and it doesn't necessarily give you the whole answer but rather gives an answer. Thus there will be possible subclasses of comonad that give you intermediate stages of picking the answer where you could control it. Probably related to the possible subclasses of Traversable. I don't know if such things are defined anywhere.
Why hoogle doesn't list this function at all appears to be because the comonad package isn't indexed otherwise I think the Monad constraint would be warned and extract would be in the results for those Monads with a Comonad instance. Perhaps this is because the hoogle parser is incomplete and fails on some lines of code.
My alternative answers:
you can perform a - possibly recursive - case analysis if you've imported the type's constructors
You can slink your code that would use the extracted values into the monad using monad >>= \a -> return $ your code uses a here as an alternative code structure and as long as you can convert the monad to "IO ()" in a way that prints your outputs you're done. This doesn't look like extraction but maths isn't the same as the real world.
Well, technicaly there is unsafePerformIO for the IO monad.
But, as the name itself suggests, this function is evil and you should only use it if you really know what you are doing (and if you have to ask wether you know or not then you don't)
I've always enjoyed the following intuitive explanation of a monad's power relative to a functor: a monad can change shape; a functor cannot.
For example: length $ fmap f [1,2,3] always equals 3.
With a monad, however, length $ [1,2,3] >>= g will often not equal 3. For example, if g is defined as:
g :: (Num a) => a -> [a]
g x = if x==2 then [] else [x]
then [1,2,3] >>= g is equal to [1,3].
The thing that troubles me slightly, is the type signature of g. It seems impossible to define a function which changes the shape of the input, with a generic monadic type such as:
h :: (Monad m, Num a) => a -> m a
The MonadPlus or MonadZero type classes have relevant zero elements, to use instead of [], but now we have something more than a monad.
Am I correct? If so, is there a way to express this subtlety to a newcomer to Haskell. I'd like to make my beloved "monads can change shape" phrase, just a touch more honest; if need be.
I've always enjoyed the following intuitive explanation of a monad's power relative to a functor: a monad can change shape; a functor cannot.
You're missing a bit of subtlety here, by the way. For the sake of terminology, I'll divide a Functor in the Haskell sense into three parts: The parametric component determined by the type parameter and operated on by fmap, the unchanging parts such as the tuple constructor in State, and the "shape" as anything else, such as choices between constructors (e.g., Nothing vs. Just) or parts involving other type parameters (e.g., the environment in Reader).
A Functor alone is limited to mapping functions over the parametric portion, of course.
A Monad can create new "shapes" based on the values of the parametric portion, which allows much more than just changing shapes. Duplicating every element in a list or dropping the first five elements would change the shape, but filtering a list requires inspecting the elements.
This is essentially how Applicative fits between them--it allows you to combine the shapes and parametric values of two Functors independently, without letting the latter influence the former.
Am I correct? If so, is there a way to express this subtlety to a newcomer to Haskell. I'd like to make my beloved "monads can change shape" phrase, just a touch more honest; if need be.
Perhaps the subtlety you're looking for here is that you're not really "changing" anything. Nothing in a Monad lets you explicitly mess with the shape. What it lets you do is create new shapes based on each parametric value, and have those new shapes recombined into a new composite shape.
Thus, you'll always be limited by the available ways to create shapes. With a completely generic Monad all you have is return, which by definition creates whatever shape is necessary such that (>>= return) is the identity function. The definition of a Monad tells you what you can do, given certain kinds of functions; it doesn't provide those functions for you.
Monad's operations can "change the shape" of values to the extent that the >>= function replaces leaf nodes in the "tree" that is the original value with a new substructure derived from the node's value (for a suitably general notion of "tree" - in the list case, the "tree" is associative).
In your list example what is happening is that each number (leaf) is being replaced by the new list that results when g is applied to that number. The overall structure of the original list still can be seen if you know what you're looking for; the results of g are still there in order, they've just been smashed together so you can't tell where one ends and the next begins unless you already know.
A more enlightening point of view may be to consider fmap and join instead of >>=. Together with return, either way gives an equivalent definition of a monad. In the fmap/join view, though, what is happening here is more clear. Continuing with your list example, first g is fmapped over the list yielding [[1],[],[3]]. Then that list is joined, which for list is just concat.
Just because the monad pattern includes some particular instances that allow shape changes doesn't mean every instance can have shape changes. For example, there is only one "shape" available in the Identity monad:
newtype Identity a = Identity a
instance Monad Identity where
return = Identity
Identity a >>= f = f a
In fact, it's not clear to me that very many monads have meaningful "shape"s: for example, what does shape mean in the State, Reader, Writer, ST, STM, or IO monads?
The key combinator for monads is (>>=). Knowing that it composes two monadic values and reading its type signature, the power of monads becomes more apparent:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
The future action can depend entirely on the outcome of the first action, because it is a function of its result. This power comes at a price though: Functions in Haskell are entirely opaque, so there is no way for you to get any information about a composed action without actually running it. As a side note, this is where arrows come in.
A function with a signature like h indeed cannot do many interesting things beyond performing some arithmetic on its argument. So, you have the correct intuition there.
However, it might help to look at commonly used libraries for functions with similar signatures. You'll find that the most generic ones, as you'd expect, perform generic monad operations like return, liftM, or join. Also, when you use liftM or fmap to lift an ordinary function into a monadic function, you typically wind up with a similarly generic signature, and this is quite convenient for integrating pure functions with monadic code.
In order to use the structure that a particular monad offers, you inevitably need to use some knowledge about the specific monad you're in to build new and interesting computations in that monad. Consider the state monad, (s -> (a, s)). Without knowing that type, we can't write get = \s -> (s, s), but without being able to access the state, there's not much point to being in the monad.
The simplest type of a function satisfying the requirement I can imagine is this:
enigma :: Monad m => m () -> m ()
One can implement it in one of the following ways:
enigma1 m = m -- not changing the shape
enigma2 _ = return () -- changing the shape
This was a very simple change -- enigma2 just discards the shape and replaces it with the trivial one. Another kind of generic change is combining two shapes together:
foo :: Monad m => m () -> m () -> m ()
foo a b = a >> b
The result of foo can have shape different from both a and b.
A third obvious change of shape, requiring the full power of the monad, is a
join :: Monad m => m (m a) -> m a
join x = x >>= id
The shape of join x is usually not the same as of x itself.
Combining those primitive changes of shape, one can derive non-trivial things like sequence, foldM and alike.
Does
h :: (Monad m, Num a) => a -> m a
h 0 = fail "Failed."
h a = return a
suit your needs? For example,
> [0,1,2,3] >>= h
[1,2,3]
This isn't a full answer, but I have a few things to say about your question that don't really fit into a comment.
Firstly, Monad and Functor are typeclasses; they classify types. So it is odd to say that "a monad can change shape; a functor cannot." I believe what you are trying to talk about is a "Monadic value" or perhaps a "monadic action": a value whose type is m a for some Monad m of kind * -> * and some other type of kind *. I'm not entirely sure what to call Functor f :: f a, I suppose I'd call it a "value in a functor", though that's not the best description of, say, IO String (IO is a functor).
Secondly, note that all Monads are necessarily Functors (fmap = liftM), so I'd say the difference you observe is between fmap and >>=, or even between f and g, rather than between Monad and Functor.