Hello I have a code which I'm trying to understand:
zipM:: Monad m => [m a] -> [m b] -> m [(a,b)]
zipM [] list = return []
zipM list [] = return []
zipM (hFirst:tFirst) (hSecond:tSecond) = do
rest <- zipM tFirst tSecond
headUnpacked <- unpack hFirst hSecond
return (headUnpacked : rest) -- rest = Just []
unpack ::Monad m => m a -> m b -> m (a,b)
unpack first second = do
fi <- first
se <- second
return (fi, se)
Generally I got a point but still have problem at two moments.
How to call 'unpack' in console ? I tried unpack (Just 5) and it's causing an error.
Since 'rest' is 'Just []' how can I perform simple list add?
I tried (Just 4): (Just []) and also (Just [1,2]): (Just [2,3]) both of which result in errors.
I'll be most grateful if someone will show with some basic explanation how to perform this two actions.
You can use unpack in GHCi like this:
Prelude> unpack (Just 5) (Just 42)
Just (5,42)
Prelude> unpack [[42,1337],[123]] [["foo"],["bar","baz"]]
[([42,1337],["foo"]),([42,1337],["bar","baz"]),([123],["foo"]),([123],["bar","baz"])]
Prelude> :m +Data.Monoid
Prelude Data.Monoid> unpack (Product 7, "foo") (Product 6, "bar")
(Product {getProduct = 42},("foo","bar"))
Notice that the function works with any Monad, not only Maybe. The above GHCi session demonstrates that by also calling unpack with two lists, and two tuples (which are Monad instances when the first element is a Monoid).
There's nothing inherently wrong with the expression unpack (Just 5):
Prelude Data.Monoid> :t unpack (Just 5)
unpack (Just 5) :: Num a => Maybe b -> Maybe (a, b)
The reason you see an error is because, as you can see from the above type inquiry, the expression is a function. Again, there's nothing wrong with functions, but GHCi doesn't know how to render functions because it relies on the Show type class to turn expressions into printable values, and functions don't have Show instances.
To address the second question, rest isn't Just []. First, Just isn't a type, but a data constructor, but secondly, even if you meant Maybe [a], that's not necessarily true, because you don't know whether or not the Monad in question is Maybe or some other Monad.
Finally, as far as I can tell, rest is the result of calling unpack, the result of which has the type Monad m => m (a,b). Since rest is bound using do notation, it must, then, have the type (a,b), unless I'm mistaken.
Related
So I'm playing around with the hasbolt module in GHCi and I had a curiosity about some desugaring. I've been connecting to a Neo4j database by creating a pipe as follows
ghci> pipe <- connect $ def {credentials}
and that works just fine. However, I'm wondering what the type of the (<-) operator is (GHCi won't tell me). Most desugaring explanations describe that
do x <- a
return x
desugars to
a >>= (\x -> return x)
but what about just the line x <- a?
It doesn't help me to add in the return because I want pipe :: Pipe not pipe :: Control.Monad.IO.Class.MonadIO m => m Pipe, but (>>=) :: Monad m => m a -> (a -> m b) -> m b so trying to desugar using bind and return/pure doesn't work without it.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Another oddity is that, treating (<-) as haskell function, it's first argument is an out-of-scope variable, but that wouldn't mean that
(<-) :: a -> m b -> b
because not just anything can be used as a free variable. For instance, you couldn't bind the pipe to a Num type or a Bool. The variable has to be a "String"ish thing, except it never is actually a String; and you definitely can't try actually binding to a String. So it seems as if it isn't a haskell function in the usual sense (unless there is a class of functions that take values from the free variable namespace... unlikely). So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
I'm wondering what the type of the (<-) operator is ...
<- doesn't have a type, it's part of the syntax of do notation, which as you know is converted to sequences of >>= and return during a process called desugaring.
but what about just the line x <- a ...?
That's a syntax error in normal haskell code and the compiler would complain. The reason the line:
ghci> pipe <- connect $ def {credentials}
works in ghci is that the repl is a sort of do block; you can think of each entry as a line in your main function (it's a bit more hairy than that, but that's a good approximation). That's why you need (until recently) to say let foo = bar in ghci to declare a binding as well.
Ideally it seems like it'd be best to just make a Comonad instance to enable using extract :: Monad m => m a -> a as pipe = extract $ connect $ def {creds} but it bugs me that I don't understand (<-).
Comonad has nothing to do with Monads. In fact, most Monads don't have any valid Comonad instance. Consider the [] Monad:
instance Monad [a] where
return x = [x]
xs >>= f = concat (map f xs)
If we try to write a Comonad instance, we can't define extract :: m a -> a
instance Comonad [a] where
extract (x:_) = x
extract [] = ???
This tells us something interesting about Monads, namely that we can't write a general function with the type Monad m => m a -> a. In other words, we can't "extract" a value from a Monad without additional knowledge about it.
So how does the do-notation syntax do {x <- [1,2,3]; return [x,x]} work?
Since <- is actually just syntax sugar, just like how [1,2,3] actually means 1 : 2 : 3 : [], the above expression actually means [1,2,3] >>= (\x -> return [x,x]), which in turn evaluates to concat (map (\x -> [[x,x]]) [1,2,3])), which comes out to [1,1,2,2,3,3].
Notice how the arrow transformed into a >>= and a lambda. This uses only built-in (in the typeclass) Monad functions, so it works for any Monad in general.
We can pretend to extract a value by using (>>=) :: Monad m => m a -> (a -> m b) -> m b and working with the "extracted" a inside the function we provide, like in the lambda in the list example above. However, it is impossible to actually get a value out of a Monad in a generic way, which is why the return type of >>= is m b (in the Monad)
So what is (<-) exactly? Can it be replaced entirely by using extract? Is that the best way to desugar/circumvent it?
Note that the do-block <- and extract mean very different things even for types that have both Monad and Comonad instances. For instance, consider non-empty lists. They have instances of both Monad (which is very much like the usual one for lists) and Comonad (with extend/=>> applying a function to all suffixes of the list). If we write a do-block such as...
import qualified Data.List.NonEmpty as N
import Data.List.NonEmpty (NonEmpty(..))
import Data.Function ((&))
alternating :: NonEmpty Integer
alternating = do
x <- N.fromList [1..6]
-x :| [x]
... the x in x <- N.fromList [1..6] stands for the elements of the non-empty list; however, this x must be used to build a new list (or, more generally, to set up a new monadic computation). That, as others have explained, reflects how do-notation is desugared. It becomes easier to see if we make the desugared code look like the original one:
alternating :: NonEmpty Integer
alternating =
N.fromList [1..6] >>= \x ->
-x :| [x]
GHCi> alternating
-1 :| [1,-2,2,-3,3,-4,4,-5,5,-6,6]
The lines below x <- N.fromList [1..6] in the do-block amount to the body of a lambda. x <- in isolation is therefore akin to a lambda without body, which is not a meaningful thing.
Another important thing to note is that x in the do-block above does not correspond to any one single Integer, but rather to all Integers in the list. That already gives away that <- does not correspond to an extraction function. (With other monads, the x might even correspond to no values at all, as in x <- Nothing or x <- []. See also Lazersmoke's answer.)
On the other hand, extract does extract a single value, with no ifs or buts...
GHCi> extract (N.fromList [1..6])
1
... however, it is really a single value: the tail of the list is discarded. If we want to use the suffixes of the list, we need extend/(=>>)...
GHCi> N.fromList [1..6] =>> product =>> sum
1956 :| [1236,516,156,36,6]
If we had a co-do-notation for comonads (cf. this package and the links therein), the example above might get rewritten as something in the vein of:
-- codo introduces a function: x & f = f x
N.fromList [1..6] & codo xs -> do
ys <- product xs
sum ys
The statements would correspond to plain values; the bound variables (xs and ys), to comonadic values (in this case, to list suffixes). That is exactly the opposite of what we have with monadic do-blocks. All in all, as far as your question is concerned, switching to comonads just swaps which things we can't refer to outside of the context of a computation.
I am using the Writer monad to keep track of an error ("collision") flag on arbitrary values (such as Int). Once the flag is set it is "sticky" and attaches itself to all values produced as a result of any operation with the marked one.
Sometimes the collision flag is associated with individual values, sometimes I would like to associate with composite structures such as lists. Of course, once the collision flag is set for a whole list, it also makes sense to assume it is set for an individual element. So for a writer monad m I need the two following operations:
sequence :: [m a] -> m [a]
unsequence :: m [a] -> [m a]
The first one is defined in the Prelude, while the second one has to be defined. Here is a good discussion of how it could be defined using comonads. A native comonad implementation does not preserve the state. Here is an example:
{-# LANGUAGE FlexibleInstances #-}
module Foo where
import Control.Monad.Writer
import Control.Comonad
unsequence :: (Comonad w, Monad m) => w [a] -> [m a]
unsequence = map return . extract
instance Monoid Bool where
mempty = False
mappend = (||)
type CM = Writer Bool
type CInt = CM Int
instance (Monoid w) => Comonad (Writer w) where
extract x = fst $ runWriter x
extend f wa = do { tell $ execWriter wa ; return (f wa)}
mkCollision :: t -> Writer Bool t
mkCollision x = do (tell True) ; return x
unsequence1 :: CM [Int] -> [CInt]
unsequence1 a = let (l,f) = runWriter a in
map (\x -> do { tell f ; return x}) l
el = mkCollision [1,2,3]
ex2:: [CInt]
ex2 = unsequence el
ex1 = unsequence1 el
The ex1 produces the correct value, while ex2 output is incorrectly not preserving collision flag:
*Foo> ex1
[WriterT (Identity (1,True)),WriterT (Identity (2,True)),WriterT (Identity (3,True))]
*Foo> ex2
[WriterT (Identity (1,False)),WriterT (Identity (2,False)),WriterT (Identity (3,False))]
*Foo>
In view of this I have 2 questions:
Is it possible to define unsequence using monadic and comonadic operators, not specific to Writer?
Is there is a more elegant implementation of the extend function above, perhaps similar to this one?
Thanks!
The ex1 produces correct value, while ex2 output is incorrectly not preserving collision flag:
unsequence (and, as a consequence, ex2) doesn't work because it throws away the Writer log.
unsequence :: (Comonad w, Monad m) => w [a] -> [m a]
unsequence = map return . extract
extract for your Comonad instance gives the result of the computation, discarding the log. return adds a mempty log to the bare results. That being so, the flags are cleared in ex2.
unsequence1, on the other hand, does what you want. That clearly doesn't have anything to do with Comonad (your definition doesn't use its methods); rather, unsequence1 works because... it's actually sequence! Under the hood, Writer is just a pair of a result and a (monoidal) log. If you have a second look at unsequence1 with that in mind, you will note that (modulo irrelevant details) it does essentially the same thing than sequence for pairs -- it annotates the values in the other functor with the log:
GHCi> sequence (3, [1..10])
[(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(3,7),(3,8),(3,9),(3,10)]
In fact, Writer already has a Traversable instance just like that, so you don't even need to define it:
GHCi> import Control.Monad.Writer
GHCi> import Data.Monoid -- 'Any' is your 'Bool' monoid.
GHCi> el = tell (Any True) >> return [1,2,3] :: Writer Any [Int]
GHCi> sequence el
[WriterT (Identity (1,Any {getAny = True})),WriterT (Identity (2,Any {getAny = True})),WriterT (Identity (3,Any {getAny = True}))]
It is worth mentioning that sequence isn't an essentially monadic operation -- the Monad constraint in sequence is unnecessarily restrictive. The real deal is sequenceA, which only requires an Applicative constraint on the inner functor. (If the outer Functor -- i.e. the one with the Traversable instance -- is like Writer w in that it always "holds" exactly one value, then you don't even need Applicative, but that's another story.)
Is it possible to define 'unsequence' using monadic and comonadic operators, not specific to 'Writer'
As discussed above, you don't actually want unsequence. There is a class called Distributive that does provide unsequence (under the name of distribute); however, there is relatively little overlap between things with Distributive instances and things with Traversable ones, and in any case it doesn't essentially involve comonads.
Is there is a more elegant implementatoin of extend function above, perhaps similar to this one?
Your Comonad instance is fine (it does follow the comonad laws), except that you don't actually need the Monoid constraint in it. The pair comonad is usually known as Env; see this answer for discussion of what it does.
i have a list with functions and one other list with "arguments" to make a new list where each element of the one list, map with the other element of the other list. (apply :: Ord u => [v->u]->[v]->[u] )
For example,
apply [(^2),(^3),(^4),(2^)] [10] = [100,1000,1024,10000]. or
apply [reverse,(++"ing"),reverse.(++"ing"),(++"ing").reverse] ["play","do"] = ["doing","gniod","gniyalp","od","oding","playing","yalp","yalping"]..
What can i do, because i do my first steps in haskel..
Let us take your first list:
[(^2),(^3),(^4),(2^)]
It's type is xs :: Integral a => [a -> a]
Now you want to apply it to to a list [10]. What you want is exactly Applicative function <*> whose type is Applicative f => f (a -> b) -> f a -> f b:
λ> import Control.Applicative
λ> let xs = [(^2),(^3),(^4),(2^)]
λ> xs <*> [10]
[100,1000,10000,1024]
You can work out the types to see how they fit together. Your second example doesn't seem to be correct as you are not passing any second parameter to your apply function. I would suggest you to start reading LYAH to further solidify the concepts.
I need a function which will choose a non-empty monoid. For a list this will mean the following behaviour:
> [1] `mor` []
[1]
> [1] `mor` [2]
[1]
> [] `mor` [2]
[2]
Now, I've actually implemented it but am wondering wether there exists some standard alternative, because it seems to be a kind of a common case. Unfortunately Hoogle doesn't help.
Here's my implementation:
mor :: (Eq a, Monoid a) => a -> a -> a
mor a b = if a /= mempty then a else b
If your lists contain at most one element, they're isomorphic to Maybe, and for that there's the "first non empty" monoid: First from Data.Monoid. It's a wrapper around Maybe a values, and mappend returns the first Just value:
import Data.Monoid
main = do
print $ (First $ Just 'a') <> (First $ Just 'b')
print $ (First $ Just 'a') <> (First Nothing)
print $ (First Nothing) <> (First $ Just 'b')
print $ (First Nothing) <> (First Nothing :: First Char)
==> Output:
First {getFirst = Just 'a'}
First {getFirst = Just 'a'}
First {getFirst = Just 'b'}
First {getFirst = Nothing}
Conversion [a] -> Maybe a is achieved using Data.Maybe.listToMaybe.
On a side note: this one does not constrain the typeclass of the wrapped type; in your question, you need an Eq instance to compare for equality with mempty. This comes at the cost of having the Maybe type, of course.
[This is really a long comment rather than an answer]
In my comment, when I said "monoidal things have no notion of introspection" - I meant that you can't perform analysis (pattern matching, equality, <, >, etc.) on monoids. This is obvious of course - the API of Monoids is only unit (mempty) and an operation mappend (more abstractly <>) that takes two monodial things and returns one. The definition of mappend for a type is free to use case analysis, but afterwards all you can do with monoidal things is use the Monoid API.
It's something of a folklore in the Haskell community to avoid inventing things, prefering instead to use objects from mathematics and computer science (including functional programming history). Combining Eq (which needs analysis of is arguments) and Monoid introduces a new class of things - monoids that support enough introspection to allow equality; and at this point there is a reasonable argument that an Eq-Monoid thing goes against the spirit of its Monoid superclass (Monoids are opaque). As this is both a new class of objects and potentially contentious - a standard implementation won't exist.
First, your mor function looks rather suspicious because it requires a Monoid but never uses mappend, and so it is significantly more constrained than necessary.
mor :: (Eq a, Monoid a) => a -> a -> a
mor a b = if a /= mempty then a else b
You could accomplish the same thing with merely a Default constraint:
import Data.Default
mor :: (Eq a, Default a) => a -> a -> a
mor a b = if a /= def then a else b
and I think that any use of Default should also be viewed warily because, as I believe many Haskellers complain, it is a class without principles.
My second thought is that it seems that the data type you're really dealing with here is Maybe (NonEmpty a), not [a], and the Monoid you're actually talking about is First.
import Data.Monoid
morMaybe :: Maybe a -> Maybe a -> Maybe a
morMaybe x y = getFirst (First x <> First y)
And so then we could use that with lists, as in your example, under the (nonEmpty, maybe [] toList) isomorphism between [a] and Maybe (NonEmpty a):
import Data.List.NonEmpty
morList :: [t] -> [t] -> [t]
morList x y = maybe [] toList (nonEmpty x `mor` nonEmpty y)
λ> mor'list [1] []
[1]
λ> mor'list [] [2]
[2]
λ> mor'list [1] [2]
[1]
(I'm sure that somebody more familiar with the lens library could provide a more impressive concise demonstration here, but I don't immediately know how.)
You could extend Monoid with a predicate to test whether an element is an identity.
class Monoid a => TestableMonoid a
where
isMempty :: a -> Bool
morTestable :: a -> a -> a
morTestable x y = if isMempty x then y else x
Not every monoid can have an instance of TestableMonoid, but plenty (including list) can.
instance TestableMonoid [a]
where
isMempty = null
We could even then write a newtype wrapper with a Monoid:
newtype Mor a = Mor { unMor :: a }
instance TestableMonoid a => Monoid (Mor a)
where
mempty = Mor mempty
Mor x `mappend` Mor y = Mor (morTestable x y)
λ> unMor (Mor [1] <> Mor [])
[1]
λ> unMor (Mor [] <> Mor [2])
[2]
λ> unMor (Mor [1] <> Mor [2])
[1]
So that leaves open the question of whether the TestableMonoid class deserves to exist. It certainly seems like a more "algebraically legitimate" class than Default, at least, because we can give it a law that relates it to Monoid:
isEmpty x iff mappend x = id
But I do question whether this actually has any common use cases. As I said earlier, the Monoid constraint is superfluous for your use case because you never mappend. So we should ask, then, can we envision a situation in which one might need both mappend and isMempty, and thus have a legitimate need for a TestableMonoid constraint? It's possible I'm being shortsighted here, but I can't envision a case.
I think this is because of something Stephen Tetley touched on when he said that this "goes against the spirit of its Monoid." Tilt your head at the type signature of mappend with a slightly different parenthesization:
mappend :: a -> (a -> a)
mappend is a mapping from members of a set a to functions a -> a. A monoid is a way of viewing values as functions over those values. The monoid is a view of the world of a only through the window of what these functions let us see. And functions are very limited in what they let us see. The only thing we ever do with them is apply them. We never ask anything else of a function (as Stephen said, we have no introspection into them). So although, yes, you can bolt anything you want onto a subclass, in this case the thing we're bolting on feels very different in character from the base class we are extending, and it feels unlikely that there would be much intersection between the use cases of functions and the use cases of things that have general equality or a predicate like isMempty.
So finally I want to come back around to the simple and precise way to write this: Write code at the value level and stop worrying classes. You don't need Monoid and you don't need Eq, all you need is an additional argument:
morSimple :: (t -> Bool) -- ^ Determine whether a value should be discarded
-> t -> t -> t
morSimple f x y = if f x then y else x
λ> morSimple null [1] []
[1]
λ> morSimple null [1] [2]
[1]
λ> morSimple null [] [2]
[2]
Im trying to understand what a functor is, i found this tutorial/example:
http://en.wikibooks.org/wiki/Haskell/Solutions/Applicative_Functors
data Tree a = Node a [Tree a]
The functor for the above type being:
instance Functor Tree where
fmap f (Node a ts) = Node (f a) (map (fmap f) ts)
could someone help explain what exactly they have done and why they have done it? My understanding is that a functor allows you to iterate over a data type. I cant seem to understand the syntax used though?
A Functor is useful for mapping between two data representations. Sometimes that might resemble iteration, sometimes not. Having this common Functor typeclass allows us to ignore the actual structure of the data type (Maybe, List, Tree) and focus only on the data they contain. The author of that data type should know how that data structure might be traversed/iterated so he should provide the implementation for that (in the form of a Functor instance of that data type). All we have to provide is that function f which takes an a and maps it to a b. For example:
import Data.Char (toLower)
data Tree a = Node a [Tree a]
deriving Show
instance Functor Tree where
fmap f (Node a ts) = Node (f a) (map (fmap f) ts)
main :: IO ()
main = do print (toLower `fmap` (Node 'F' [])) -- Node 'f' []
print (toLower `fmap` (Just 'F')) -- Just 'f'
print (toLower `fmap` "FOO") -- "foo"
We were able to lowercase those chars using the same code toLower combined with fmap.
So, what you should do when defining that Functor instance is to extract inner data using pattern matching, and the apply the received callback function f to each of these results.
An infix synonym for fmap can be found in the Control.Applicative module, called <$>.
main :: IO ()
main = do print (toLower <$> (Node 'F' [])) -- Node 'f' []
print (toLower <$> (Just 'F')) -- Just 'f'
print (toLower <$> "FOO") -- "foo"
I've never seen Haskell before in my life, but I'm guessing that it's defining a data type (called Tree) that consists of a Node that contains a value, and an array of Trees (which would be the branches of the original tree). It then defines a function that operates on a function and a tree, and creates a new tree by applying the function to the Node's value, and applying itself recursively to all the branches in the array (using the map function as a shortcut).
Basically, in Haskell, you can think of a functor as:
a box that contains a value in a special context (IO, Maybe, Either a)
a structure that holds multiple values (Tree, Map a, List)
Additionally, a functor has an operation -- fmap -- that understands its specific structure.
Using fmap, you can easily apply a structure-preserving transformation to a functor. For example, fmap (+ 1) is a function that adds 1 to any functor:
Prelude> fmap (+ 1) [1,2 ] -- using a list functor
[2,3]
Prelude> fmap (+ 1) (Just 2) -- using a maybe functor
Just 3
In the example you've given, Tree is given a Functor instance -- an implementation of fmap -- that understands the structure of a tree, and abstracts that away for you.
A great resource for Functors, Applicative Functors, Monads, Monoids is Learn You A Haskell.