Search Haskell Channel Logs

Tuesday, January 31, 2017

#haskell channel featuring ski, quchen, zipper, reactormonk, roxxik, ertes,

ski 2017-01-31 02:45:19
quchen : weren't we talking about `\cl -> cl (:) []', not `\n c -> foldr c n' (nor `\as n c -> foldr c n as') ?
roxxik 2017-01-31 02:45:23
ski: so expressed in haskells limited language what would that be? \r -> f r <=> f ?
quchen 2017-01-31 02:45:49
ertes: Although in practice, making arbitrary choices during type inference is awkward.
quchen 2017-01-31 02:46:03
As in »Choose the one with the outermost foralls« or something.
ski 2017-01-31 02:46:13
roxxik : i'm not sure where this type `F f a' you mentioned comes from. were you suggesting that it was a representation of `CoDensity f a' ?
roxxik 2017-01-31 02:46:35
so \r -> Cont r (Coyoneda f r) == type ContCoyoneda f r = Cont r (Coyoneda f r)
roxxik 2017-01-31 02:46:43
no it's a representation of Free
roxxik 2017-01-31 02:47:04
it's directly from https://hackage.haskell.org/package/free-4.12.4/docs/Control-Monad-Trans-Free-Church.html specialized to Identity
ski 2017-01-31 02:47:45
(in L-lambda unification, there may be several "most general" unifiers (iow with a minimum of assumptions))
reactormonk 2017-01-31 02:47:53
Does someone have a good documentation about lenses? I have a rough idea how they work, but that's about it.
merijn 2017-01-31 02:48:19
reactormonk: There's a good talk by edwardk on youtube (and I think SPJ has a talk too)
merijn 2017-01-31 02:48:22
@where lens
lambdabot 2017-01-31 02:48:22
#haskell-lens | http://lens.github.io/ | https://github.com/ekmett/lens | http://www.youtube.com/watch?v=cefnmjtAolY&hd=1
reactormonk 2017-01-31 02:48:43
merijn, I wanted to avoid a talk, so I can read it at my own pace
ertes 2017-01-31 02:49:12
reactormonk: if you want the quickest possible intro, i can give you my patented Three Lens Exercises =)
reactormonk 2017-01-31 02:49:24
ertes, go ahead
roxxik 2017-01-31 02:49:55
ski: so F f a = Yoneda (ContCoyoneda f) a?
ertes 2017-01-31 02:50:07
reactormonk: 1. write a function that maps over the fst of a tuple: mapFst :: (a -> b) -> (a, c) -> (b, c)
reactormonk 2017-01-31 02:50:24
ertes, using which functions?
ertes 2017-01-31 02:50:31
reactormonk: whatever you like
ski 2017-01-31 02:50:38
roxxik : yep
roxxik 2017-01-31 02:51:21
ski: that's not looking particularly enligthening to me... but i'll look into it
ski 2017-01-31 02:51:25
@where SEC
lambdabot 2017-01-31 02:51:25
http://conal.net/blog/posts/semantic-editor-combinators/
ski 2017-01-31 02:51:37
reactormonk : ^ might be interesting
ski 2017-01-31 02:51:43
reactormonk : i don't think so, either ..
ski 2017-01-31 02:51:50
er
reactormonk 2017-01-31 02:51:52
:t fun f t = (fst t, snd $ f t)
ski 2017-01-31 02:51:53
roxxik ^
lambdabot 2017-01-31 02:51:54
error:
lambdabot 2017-01-31 02:51:54
parse error on input '='
lambdabot 2017-01-31 02:51:54
Perhaps you need a 'let' in a 'do' block?
reactormonk 2017-01-31 02:52:03
hmmm, how do I put them in there?
ski 2017-01-31 02:52:10
(the first suggestion was for reactormonk, though)
ertes 2017-01-31 02:52:15
:t \f t -> (fst t, snd (f t))
lambdabot 2017-01-31 02:52:17
((t, b) -> (a, t1)) -> (t, b) -> (t, t1)
ertes 2017-01-31 02:52:26
reactormonk: doesn't look right
reactormonk 2017-01-31 02:52:35
ah, first
ski 2017-01-31 02:52:43
@type let fun f t = (fst t,snd $ f t) in fun -- alternative
lambdabot 2017-01-31 02:52:45
((t, b) -> (a, t1)) -> (t, b) -> (t, t1)
reactormonk 2017-01-31 02:53:20
:t \f t = (f $ fst t , snd t)
lambdabot 2017-01-31 02:53:21
error:
lambdabot 2017-01-31 02:53:21
parse error on input '='
lambdabot 2017-01-31 02:53:21
Perhaps you need a 'let' in a 'do' block?
reactormonk 2017-01-31 02:53:34
:t \f t -> (f $ fst t , snd t)
lambdabot 2017-01-31 02:53:36
(a -> t) -> (a, t1) -> (t, t1)
ski 2017-01-31 02:53:45
good
ertes 2017-01-31 02:53:53
reactormonk: correct (hint: you can pattern-match: \f (x, y) -> (f x, y)
reactormonk 2017-01-31 02:54:11
:t \f (a, b) -> (f $ a, b)
lambdabot 2017-01-31 02:54:15
(t2 -> t) -> (t2, t1) -> (t, t1)
ertes 2017-01-31 02:54:18
reactormonk: 2. write a function that extracts the fst using a function: getFst :: (a -> r) -> (a, b) -> r
reactormonk 2017-01-31 02:54:27
:t \f (a, _) -> a
lambdabot 2017-01-31 02:54:32
t -> (t1, t2) -> t1
ertes 2017-01-31 02:54:37
nope
reactormonk 2017-01-31 02:54:42
ah, a function
reactormonk 2017-01-31 02:54:44
:t \f (a, _) -> f a
lambdabot 2017-01-31 02:54:47
(t1 -> t2) -> (t1, t) -> t2
ertes 2017-01-31 02:54:49
correct
reactormonk 2017-01-31 02:54:56
Now make a lens out of it?
ertes 2017-01-31 02:55:40
reactormonk: 3. generalise the function from exercise 1 to a traversal and see if you can come up with an 'f' that also supports the second kind of usage: traverseFst :: (Functor f) => (a -> f b) -> (a, c) -> f (b, c)
ertes 2017-01-31 02:56:01
this is like mapFst, but supports effects for the function
reactormonk 2017-01-31 02:58:11
Can I have anonymous functions with TC constraints?
ertes 2017-01-31 02:58:27
reactormonk: sure, they will be inferred
ski 2017-01-31 02:59:35
(unless you want your higher-order function to pick the constraint for the callback operation, in which case you need rank-2 ..)
reactormonk 2017-01-31 03:00:30
gotta, go, I'll scroll back in a few hours.
ertes 2017-01-31 03:01:15
reactormonk: once you get back and solve exercise 3 here is the fun part: traverseFst is a lens into the fst of tuples =)
roxxik 2017-01-31 03:02:41
:t _1 :: Lens (a,b) a
lambdabot 2017-01-31 03:02:42
error:
lambdabot 2017-01-31 03:02:42
• Expecting two more arguments to 'Lens (a, b) a'
lambdabot 2017-01-31 03:02:42
Expected a type, but 'Lens (a, b) a' has kind '* -> * -> *'
roxxik 2017-01-31 03:02:47
:t _1 :: Lens' (a,b) a
lambdabot 2017-01-31 03:02:49
Functor f => (a -> f a) -> (a, b) -> f (a, b)
ertes 2017-01-31 03:03:42
reactormonk: the idea is that with different choices for 'f' this will be either mapFst or getFst
merijn 2017-01-31 03:14:25
Is there a typeclass to show directly to Text or should I just do "T.pack . show"?
roxxik 2017-01-31 03:15:13
:t traverseOf
ertes 2017-01-31 03:15:13
merijn: the latter is fine most of the time… showsPrec is surprisingly efficient
lambdabot 2017-01-31 03:15:15
LensLike f s t a b -> (a -> f b) -> s -> f t
merijn 2017-01-31 03:15:28
ertes: It's only for logging errors anyway
merijn 2017-01-31 03:15:35
ertes: It's just so annoyingly verbose :p
ertes 2017-01-31 03:16:09
merijn: well, you don't have to use Show to use ShowS… just show the parts you care about =)
ertes 2017-01-31 03:17:08
showString "Got " . maybe (showString "nothing") (showsPrec 10) mx
merijn 2017-01-31 03:19:49
ertes: If only I had something that elegant :p
merijn 2017-01-31 03:22:08
ertes: Suggestions on how to make this suck less welcome: http://lpaste.net/2233214326259318784 :p
merijn 2017-01-31 03:22:43
hmm, maybe mconcat with a list of elements
merijn 2017-01-31 03:24:23
Is there some haskelly version of printf/format strings?
zipper 2017-01-31 03:24:40
merijn: I think from Data.Text there is
zipper 2017-01-31 03:24:46
:t Data.Text.printf
lambdabot 2017-01-31 03:24:48
error:
lambdabot 2017-01-31 03:24:48
Not in scope: 'Data.Text.printf'
lambdabot 2017-01-31 03:24:48
No module named 'Data.Text' is imported.
zipper 2017-01-31 03:24:52
What?
zipper 2017-01-31 03:25:06
:t Text.printf
lambdabot 2017-01-31 03:25:08
error:
lambdabot 2017-01-31 03:25:08
Not in scope: 'Text.printf'
lambdabot 2017-01-31 03:25:08
No module named 'Text' is imported.
zipper 2017-01-31 03:25:18
merijn: https://hackage.haskell.org/package/base-4.9.1.0/docs/Text-Printf.html
zipper 2017-01-31 03:25:26
idk why lambdabot is being mean
merijn 2017-01-31 03:25:45
Text.Printf is rather ugly, though since there's no validation
zipper 2017-01-31 03:26:20
Oh you asked a haskelly version idk what that even means :P you mean like validation that %s is taking a string?
zipper 2017-01-31 03:26:25
and %d an int?
zipper 2017-01-31 03:26:31
etc?
merijn 2017-01-31 03:27:02
Text.printf doesn't even check it gets the right number of arguments
zipper 2017-01-31 03:27:18
Oh
ertes 2017-01-31 03:27:30
merijn: if you lay out that code properly it doesn't look so ba
ertes 2017-01-31 03:27:31
bad
merijn 2017-01-31 03:27:50
ertes: I'm not sure how to lay it out properly, though, that's my problem :)
zipper 2017-01-31 03:29:43
merijn: I'm debugging JS from my DOM using XPath right now stop making me feel bad :(
ertes 2017-01-31 03:30:00
merijn: see annotation
merijn 2017-01-31 03:30:52
ertes: Yeah I was thinking of doing similar, but with mconcat and a list
ertes 2017-01-31 03:31:30
merijn: BTW, i would expect this to be more efficient, if you do all of the rendering with ShowS
zipper 2017-01-31 03:31:49
ertes: ShowS?
ski 2017-01-31 03:32:09
@src ShowS
lambdabot 2017-01-31 03:32:09
type ShowS = String -> String
ertes 2017-01-31 03:32:12
logErrorN . ($ "") $ showString "Wrong duplicate rating for game #" . shows k . …
ski 2017-01-31 03:32:22
@src Show
lambdabot 2017-01-31 03:32:22
class Show a where
lambdabot 2017-01-31 03:32:23
showsPrec :: Int -> a -> ShowS
lambdabot 2017-01-31 03:32:23
show :: a -> String
lambdabot 2017-01-31 03:32:23
showList :: [a] -> ShowS
ski 2017-01-31 03:32:29
@type showParen
ertes 2017-01-31 03:32:29
alternatively you can use the Builder interface for Text
lambdabot 2017-01-31 03:32:30
Bool -> ShowS -> ShowS
ski 2017-01-31 03:32:32
@type showString
lambdabot 2017-01-31 03:32:34
String -> ShowS
ski 2017-01-31 03:32:36
@type showChar
lambdabot 2017-01-31 03:32:38
Char -> ShowS
merijn 2017-01-31 03:32:51
ertes: Probably, but from my one small sample to end up with say 2 errors per 200-300 entries, so not too worried about performance
ski 2017-01-31 03:33:24
@type [showFFloat,showEFloat,showGFloat]
lambdabot 2017-01-31 03:33:26
RealFloat a => [Maybe Int -> a -> ShowS]
merijn 2017-01-31 03:33:31
ertes: Additionally, I have plenty of time for processing, since my queries are rate limited anyway :p
ski 2017-01-31 03:35:03
see `Numeric' for a couple of more
merijn 2017-01-31 03:35:36
oh, this seems like a good application of "appEndo . mconcat . coerce" :p
ertes 2017-01-31 03:35:38
merijn: it's probably also easier to write, because you have all the rendering options =)
merijn 2017-01-31 03:35:52
:t appEndo . mconcat . coerce
lambdabot 2017-01-31 03:35:54
error:
lambdabot 2017-01-31 03:35:54
Variable not in scope: coerce :: a1 -> [Endo a]
ertes 2017-01-31 03:35:56
not sure if it's useful in your case though
merijn 2017-01-31 03:35:57
aww
merijn 2017-01-31 03:36:43
:t appEndo . mconcat . coerce $ [id]
lambdabot 2017-01-31 03:36:45
error:
lambdabot 2017-01-31 03:36:45
Variable not in scope: coerce :: [a0 -> a0] -> [Endo a]
merijn 2017-01-31 03:36:56
Shouldn't that work?
ertes 2017-01-31 03:37:02
@let import Data.Coerce
lambdabot 2017-01-31 03:37:03
.L.hs:80:1: error:
lambdabot 2017-01-31 03:37:03
Data.Coerce: Can't be safely imported!
lambdabot 2017-01-31 03:37:03
The module itself isn't safe.
merijn 2017-01-31 03:37:16
oh, misread the error
ertes 2017-01-31 03:37:44
you've fallen for "there's a type, so it must be a type error" =)
c_wraith 2017-01-31 03:38:15
I always think appEndo sounds like a spell from Harry Potter
merijn 2017-01-31 03:38:27
c_wraith: Well, it is basically magic...
merijn 2017-01-31 03:40:42
Magic oneliner: "renderString = T.pack . ($"") . appEndo . mconcat . coerce"
merijn 2017-01-31 03:40:50
The only ugly bit is ($"")
ertes 2017-01-31 03:41:22
merijn: if you want to go overboard, you can implement a printf-style interface for logErrorN =)