Search Haskell Channel Logs

Tuesday, February 21, 2017

#haskell channel featuring Jaak, Cooler, merijn, Rembane, lambdabot, bollu,

ertes 2017-02-21 00:49:46
> not . null . concatMap (maybe [] pure) $ [Nothing]
lambdabot 2017-02-21 00:49:50
False
ertes 2017-02-21 00:49:58
> not . null . concatMap (maybe [] pure) $ (Nothing : Just 5 : repeat Nothing)
lambdabot 2017-02-21 00:50:01
True
ertes 2017-02-21 00:50:06
Jaak: better
ertes 2017-02-21 00:50:31
i can actually tell what this code does without @unpl-ing it in my head =)
ertes 2017-02-21 00:51:04
:t or . fmap (maybe False (const True))
lambdabot 2017-02-21 00:51:10
(Foldable t, Functor t) => t (Maybe b) -> Bool
ertes 2017-02-21 00:51:11
even better
ertes 2017-02-21 00:51:35
except that it requires Functor
Jaak 2017-02-21 00:51:51
i'm bummed about the maybe tho, not easy generalize
ertes 2017-02-21 00:52:06
:t or . fmap (foldr (\_ _ -> True) False)
lambdabot 2017-02-21 00:52:08
(Foldable t1, Foldable t, Functor t) => t (t1 a) -> Bool
ertes 2017-02-21 00:52:14
Jaak: better?
ertes 2017-02-21 00:52:30
or rather
ertes 2017-02-21 00:52:36
:t or . fmap (not . null)
lambdabot 2017-02-21 00:52:38
(Foldable t1, Foldable t, Functor t) => t (t1 a) -> Bool
bollu 2017-02-21 00:53:15
:t or
lambdabot 2017-02-21 00:53:18
Foldable t => t Bool -> Bool
bollu 2017-02-21 00:53:38
ah, that is cool.
Jaak 2017-02-21 00:53:46
hmm, not really, the aim was to write "generic" isFoo function where Foo is some constructor
bollu 2017-02-21 00:54:10
so, you replace every Maybe with True / False based on (not. null), exploiting the fact that it is a foldable, and then use "or" to or all the Bools, right?
Jaak 2017-02-21 00:54:17
as in isFoo x = or[True|Foo{}<-[x]]
ertes 2017-02-21 00:54:25
:t foldr ((||) . not . null) False
lambdabot 2017-02-21 00:54:27
(Foldable t1, Foldable t) => t (t1 a) -> Bool
bollu 2017-02-21 00:54:43
ertes: can you non mconcat?
merijn 2017-02-21 00:54:49
Jaak: You can't really write a generic version like that since there's no "first-class" patterns
bollu 2017-02-21 00:54:50
ertes: with Any?
ertes 2017-02-21 00:55:06
bollu: sure
bollu 2017-02-21 00:55:21
merijn: I think you can with lens
bollu 2017-02-21 00:55:28
merijn: take a prism as a parameter and use "has"
ertes 2017-02-21 00:55:31
:t getAny . foldMap (Any . not . null)
lambdabot 2017-02-21 00:55:33
(Foldable t1, Foldable t) => t (t1 a) -> Bool
ertes 2017-02-21 00:55:38
bollu: ^
merijn 2017-02-21 00:55:39
bollu: prisms aren't general
Jaak 2017-02-21 00:55:44
merijn: hmm, figured something like that. was curious if one could write than version even in a more pointless style :p
merijn 2017-02-21 00:55:46
bollu: You need to handwrite one for each constructor
bollu 2017-02-21 00:56:07
merijn: but you can makePrisms?
bollu 2017-02-21 00:56:17
ertes: neat
bollu 2017-02-21 00:56:27
:t foldMap
merijn 2017-02-21 00:56:27
Sure, but you can trivially write TemplateHaskell for what Jaak wants too
lambdabot 2017-02-21 00:56:30
(Monoid m, Foldable t) => (a -> m) -> t a -> m
bollu 2017-02-21 00:56:37
oh, neat
bollu 2017-02-21 00:56:41
:t mconcat
lambdabot 2017-02-21 00:56:45
Monoid a => [a] -> a
ertes 2017-02-21 00:57:06
if you want mconcat, you need Functor again
ertes 2017-02-21 00:57:23
:t getAny . mconcat . fmap (Any . not . null)
lambdabot 2017-02-21 00:57:25
Foldable t => [t a] -> Bool
ertes 2017-02-21 00:57:35
and it's less general, too
ertes 2017-02-21 00:57:41
uhm
bollu 2017-02-21 00:57:41
yeah
ertes 2017-02-21 00:57:44
yeah, that was non-sense =)
bollu 2017-02-21 00:57:49
because it is specialised to []
ertes 2017-02-21 00:57:53
if you want mconcat, it's less general =)
bollu 2017-02-21 00:57:59
:)
bollu 2017-02-21 00:58:07
not "necessarily"
bollu 2017-02-21 00:58:11
ertes: I can use toList :P
ertes 2017-02-21 00:58:14
but foldMap is basically mconcat on steroids
bollu 2017-02-21 00:58:19
yeah, I can see that.
bollu 2017-02-21 00:58:22
:t foldMap
lambdabot 2017-02-21 00:58:26
(Monoid m, Foldable t) => (a -> m) -> t a -> m
ertes 2017-02-21 00:58:38
:t getAny . fold . fmap (Any . not . null)
lambdabot 2017-02-21 00:58:41
(Foldable t1, Foldable t, Functor t) => t (t1 a) -> Bool
bollu 2017-02-21 00:58:42
ertes: it's quite cute, it transforms each element into the monoid and then collapses it
ertes 2017-02-21 00:58:51
yeah
bollu 2017-02-21 00:58:52
ertes: I should know Foldable better
ertes 2017-02-21 00:58:58
it's MapReduce without the parallelism =)
bollu 2017-02-21 00:59:08
ertes: xD
ertes 2017-02-21 01:08:25
another question about unsafePerformIO: in order to prevent let-floating, would it be enough to force an arbitrary function argument? like: f x y = _ where ref = unsafePerformIO (y `seq` newIORef Nothing); {-# NOINLINE ref #-}
ertes 2017-02-21 01:08:52
preferably: is there a way to do it without forcing anything?
ertes 2017-02-21 01:09:56
it would be extremely useful to have a pragma for such things that does everything necessary to make it safe: {-# UNSAFE_IO ref #-}
Cooler 2017-02-21 01:19:06
in this book, it says you can accumulate errors with applicative, but with monad it short circuits on the first error?
Cooler 2017-02-21 01:19:18
i am paraphrasing
Cooler 2017-02-21 01:19:46
why is that?
Cooler 2017-02-21 01:20:37
so you can accumulate errors with the Validation datatype
Rembane 2017-02-21 01:20:40
Because both behaviours are useful.
Cooler 2017-02-21 01:20:44
why can
Cooler 2017-02-21 01:20:50
't you do the same with monad/
Cooler 2017-02-21 01:20:54
?
Rembane 2017-02-21 01:20:56
And they are defined that way.
guardianN 2017-02-21 01:21:02
bok bok
Cooler 2017-02-21 01:21:57
"Note that Either always short-circuits on the first thing to have failed. It
Cooler 2017-02-21 01:21:57
must because in the Monad, later values can depend on previous ones:"
sbrg 2017-02-21 01:21:58
Cooler: well, "applicative" and "monad" are just patterns, so to speak. how exactly the semantics are defined depends on each instance definition.
sbrg 2017-02-21 01:22:18
there is a difference between what can be achieved in terms of power and such when it comes to applicative and monad, so maybe that's what you're looking for?
Cooler 2017-02-21 01:22:19
it says it "must" do that
sbrg 2017-02-21 01:22:51
Cooler: yes, that's one way to make (Either a) an instance of Monad. it's a pretty useful one, but there are others that make sense and are also useful
Cooler 2017-02-21 01:23:39
well it sounds like its saying no
sbrg 2017-02-21 01:24:30
Cooler: the way that Either has been made an instance of Monad in the base libraries exhibits the semantics described above
sbrg 2017-02-21 01:25:10
it also makes sense, since if you have a computation that at some point depends on previous computations to (successfully) return a value so that they can continue, it obv. can't continue if it didn't successfully return a value
Cooler 2017-02-21 01:25:42
"you can't make a Monad for Validation that
Cooler 2017-02-21 01:25:42
accumulates the errors like the Applicative does."
Cooler 2017-02-21 01:26:05
its saying no
cocreature 2017-02-21 01:35:02
Cooler: the problem is that if you have something like "Failure e >>= f" you can't apply f to anything and check if it evaluates to Failure e' so that you can then combine them with mappend
Cooler 2017-02-21 01:36:04
cocreature, why isn't that a problem with Applicative?
cocreature 2017-02-21 01:37:15
Cooler: because the left and the right argument of <*> are independent, so you can check if the right one is Failure even if the left one is Failure
cocreature 2017-02-21 01:37:40
:t (>>=)
lambdabot 2017-02-21 01:37:43
Monad m => m a -> (a -> m b) -> m b
Cooler 2017-02-21 01:38:03
:t (<*>)
cocreature 2017-02-21 01:38:05
you don't get the "a" if the first argument evaluates to "Failure e"
lambdabot 2017-02-21 01:38:08
Applicative f => f (a -> b) -> f a -> f b
Cooler 2017-02-21 01:38:45
they look similar
Cooler 2017-02-21 01:38:57
oh wait i get it
Cooler 2017-02-21 01:39:12
its because the structure is outside the function
Cooler 2017-02-21 01:39:31
whereas with monad you need to apply the function to get the structure
cocreature 2017-02-21 01:40:10
yep, and applying the function requires, that the first argument evaluates to Success a, so you get an argument that you can apply the function to
bollu 2017-02-21 01:40:54
what is the difference between "mtl" and "transformers"?
merijn 2017-02-21 01:41:13
bollu: mtl provides convenience type classes for use with transformers
bollu 2017-02-21 01:41:20
I see
Cooler 2017-02-21 01:41:44
data Sum a b = First a | Second b deriving (Eq, Show)
merijn 2017-02-21 01:41:48
So you can use transformers without mtl, but not mtl without transformers
Cooler 2017-02-21 01:41:49
(<*>) (First e) _ = (First e)
Cooler 2017-02-21 01:42:02
can i not take the function out of First and apply it?
Cooler 2017-02-21 01:42:28
(<*>) (First e) (Second a) = Second (f a)
Cooler 2017-02-21 01:42:57
or
cocreature 2017-02-21 01:42:59
Cooler: the important part is that you can do (<*>) (First e) (First e') = First (mappend e e')
Cooler 2017-02-21 01:43:02
(<*>) (First e) (Second a) = First (f a)
Cooler 2017-02-21 01:43:44
no theres no monoid type constraint
cocreature 2017-02-21 01:44:01
what is "f" supposed to be here? that variable doesn't exist
Cooler 2017-02-21 01:44:11
(<*>) (First f) (Second a) = First (f a)
cocreature 2017-02-21 01:44:18
that won't typecheck
Cooler 2017-02-21 01:44:19
is that not valid
cocreature 2017-02-21 01:44:39
try it :)