00:01
<Zemyla>
Or maybe it's the other way around. f a -> f (f (f a)).
00:02
<Zemyla>
Because I know contrareturn would be a -> f (f a).
00:03
defaultnick___ joined
00:03
uglyfigurine joined
00:04
<Ptival>
is there a known trick to deal with a state monad where certain parts of the code should only have read-only access to certain parts of the state?
00:04
<Ptival>
seems lens-y
00:05
<jle`>
Ptival: there's a common readOnly pattern
00:05
<michalrus>
jle`: so that’s what glguy suggested, also. (: I’ll look into that, looks much more interesting than IoRef. Thank you, to both of you!
00:05
<jle`>
readOnly :: Reader s a -> State s a
00:05
<jle`>
and you can use 'zoom' on the result
00:06
<jle`>
zoom :: Lens s t -> State t a -> State s a
00:06
<Ptival>
ah yeah that could help
00:06
<jle`>
i'm not sure if there's a pre-written way that combines them, though
00:07
<jle`>
i've only seen readOnly as an idiom but I haven't seen it defined anywhere
00:07
<Ptival>
the idea is my state has a global component, and a local component, and some functions should have read-only access to the global part and read-write to local, while the toplevel code is allowed to modify the global
00:07
<jle`>
so `zoom _1 . readOnly $ do ....`, the do block would be a Reader with access to the first item in a tuple state
00:07
<Ptival>
I could also make the local parts just run in a different state monad I guess
00:08
<Ptival>
maybe it would be simpler
00:08
<jle`>
yeah, the typical way is to write the local parts in a State monad that has only small portion of the global state as its state
00:08
<Ptival>
to put (Reader GlobalState, State LocalState) or something
00:08
<Ptival>
makes sense :)
00:08
<jle`>
and then use 'zoom' to use it as a part of a bigger fatty state type
00:08
<Ptival>
thanks for the brainstorming
00:08
<jle`>
no problem :)
00:09
<Zemyla>
Yeah, because contrabind would be f a -> (b -> f (f a)) -> f b.
00:09
<jle`>
\me . o ( zoom _1 . readOnly :: Reader r a -> State (r, s) a )
00:09
<robkennedy>
Is DPH still active? I can't find a repo that compiles with ghc 8, but it seems perfect for my usecase
00:10
<robkennedy>
In particular, is there an implementation for the syntax SPJ mentions: `[: 1,2,3 :]`
00:15
<robkennedy>
@pl \a -> \f g -> (,) <$> f a <*> g a
00:15
<lambdabot>
((((,) <$>) .) .) . ap (flip . (((.) . (<*>)) .) . flip id) (flip id)
00:15
<Ptival>
oh, but if I have (MonadReader T m, MonadState T m), how do I make sure from the caller point of view that it's not the State monad filling in the Reader task?
00:17
<glguy>
Ptival: By using those constraints you're saying you don't care
00:17
<robkennedy>
@pl \a -> let f x = if null x then Nothing else Just (length x) in (,) <$> listToMaybe a <*> f a
00:17
<lambdabot>
flip (((,) <$>) .) (ap (flip if' Nothing . null) (Just . length)) . ap ((.) . (<*>) . listToMaybe) (flip id)
00:17
<dunx>
nnpppp/buffer 45
00:17
<robkennedy>
Damn lambdabot too clever
00:17
<Ptival>
glguy: so I'd need a newtype to be able to discriminate?
00:18
defaultnick__ joined
00:18
<glguy>
Ptival: Just pick an 'm' that has the behavior you want
00:20
<robkennedy>
@djinn (x -> Maybe a) -> (x -> Maybe b) -> x -> Maybe (a,b)
00:20
<lambdabot>
f a b c =
00:20
<lambdabot>
case b c of
00:20
<lambdabot>
Nothing -> Nothing
00:20
<lambdabot>
Just d -> case a c of
00:20
<lambdabot>
Nothing -> Nothing
00:20
<lambdabot>
Just e -> Just (e, d)
00:20
<glguy>
robkennedy: You can play with lambdabot in /msg
00:21
<robkennedy>
Sorry. Apart from the distraction: do you know the status of DPH?
00:30
<`Guest03>
@pl \name loc -> attributeLocation prog name $= loc
00:30
<lambdabot>
($=) . attributeLocation prog
00:31
defaultnick_ joined
00:32
<nilof>
What alternative preludes are the most used?
00:32
<Welkin>
I think most people don't bother with any prelude
00:33
<Welkin>
I've used classy-prelude in the past, but it is overly complex
00:33
<Welkin>
all the prelude does it re-export other modules
00:34
<Jenaf>
Hi there! I'm beeing stupid right now
00:34
<Jenaf>
whats the equivalent to "map" for Data.Sequence
00:34
<Welkin>
is that a bee joke?
00:34
<Welkin>
Jenaf: fmap
00:34
<Welkin>
fmap is the generic map
00:34
<lambdabot>
Functor f => (a -> b) -> f a -> f b
00:35
<Jenaf>
okay, do i need to import it from traversable or so?
00:36
<Koterpillar>
it is in Prelude
00:37
<`Guest03>
why don't modules export specialized functions with standard names?
00:37
lambda-11235 joined
00:37
<`Guest03>
like map in this case
00:37
<Welkin>
fmap is the standard...
00:37
<`Guest03>
map is too
00:38
<Welkin>
map is the weird one that is specialized to List
00:38
<`Guest03>
Data.Sequence.map would be specialized to Seq
00:38
<inferno-cop>
Welkin: Does map only exist for historical reasons?
00:38
<Welkin>
fmap is what you want
00:38
<`Guest03>
maybe i like to use specialized functions
00:38
<`Guest03>
for extra type robustness
00:38
<`Guest03>
or whatever
00:39
<`Guest03>
is it so hard?
00:39
<Welkin>
I assume that the 'f' stands for "Functor", as in, "functor map"
00:39
<pacak>
`Guest03: Specialized functions are actually worse
00:39
<pacak>
For example
00:39
<pacak>
There's only one implementation (ignoring bottoms)
00:40
<pacak>
:t id (Int -> Int)
00:40
<Welkin>
I have felt the pain of using specialized functions for everything when using Elm
00:40
<lambdabot>
Pattern syntax in expression context: Int -> Int
00:40
<lambdabot>
Did you mean to enable TypeApplications?
00:40
<pacak>
there are a whole bunch of versions
00:40
<Welkin>
you have to explictly import and qualify *everything*
00:40
<lambdabot>
(a -> b) -> [a] -> [b]
00:40
<lambdabot>
Functor f => (a -> b) -> f a -> f b
00:40
<Koterpillar>
`Guest03: Elm does that, and it's a pain
00:41
<`Guest03>
anyway map not only carries that, but also promise that it won't reorder and duplicate elements
00:41
<pacak>
function with map's type signature can change the shape, fmap - does not.
00:41
<pacak>
Not in the type signature
00:41
<lambdabot>
map _ [] = []
00:41
<lambdabot>
map f (x:xs) = f x : map f xs
00:41
<inferno-cop>
I think it's bad enough that there aren't general versions of collection functions like (!), insert etc
00:41
<Welkin>
map is actually defined using fmap
00:41
<Welkin>
so, it gives you no benefits whatsoever
00:42
<Welkin>
! is only used for Vector, !! for List
00:42
<Welkin>
!! is almost never used for any reason
00:42
<`Guest03>
Welkin: what should i use: singleton or return?
00:42
<Welkin>
because List indexing is slow
00:42
<Koterpillar>
`Guest03: there's another choice, pure
00:43
<Welkin>
use pure o.o
00:43
<`Guest03>
are you sure?
00:43
<Welkin>
unless you want to be explicit and use Map.singleton
00:43
<`Guest03>
what if we are deep down in layers of Applicative?
00:43
<inferno-cop>
But I mean, you have Data.Map.! and Data.Array.! for example
00:43
<Welkin>
that's fine
00:43
<inferno-cop>
And you have to qualify them if you've got both in scope (I think?)
00:43
<Welkin>
you have to qualify Vector, Array, etc almost every time anyway
00:44
<Welkin>
because they share similar apis with List
00:44
<Welkin>
at least Vector does
00:44
<`Guest03>
Welkin: that would be V., A., ...
00:44
<Welkin>
I am not sure what your point is
00:44
<inferno-cop>
Yeah, why can't we just have a Indexable typeclass or something, so we don't have to qualify
00:44
<`Guest03>
i want to be explicit when i want
00:45
<Welkin>
fmap comes from the Functor typeclass
00:45
<`Guest03>
specialized = explicit
00:45
<`Guest03>
abot the type
00:45
<Welkin>
! does not have a typeclass
00:45
<`Guest03>
by the way
00:45
<`Guest03>
why the names ! and !! were chosen?
00:45
<inferno-cop>
It doesn't, but I am saying the world may be a better place if it had a typeclass
00:46
<Welkin>
inferno-cop: that has been taken to its logical extreme with classy-prelude
00:46
<Welkin>
and it's a monster
00:46
<Welkin>
too many typeclasses makes the code impossible to understand
00:46
<glguy>
gaudy-prelude?
00:46
<inferno-cop>
Oh, I hadn't heard about that, but I can definitely imagine it...
00:46
<Welkin>
I think the name 'classy' refers to typeclasses :P
00:47
<`Guest03>
inferno-cop: in that case, either that typeclass had to provide algorithm complexity restrictions or hadn't
00:47
<`Guest03>
in first case, there are less !'s which could make it into the typeclass
00:47
<`Guest03>
in the second case, you can write less code or be less sure about its complexity
00:48
<`Guest03>
have to *
00:48
<Welkin>
`Guest03: not having generic functions like `fmap` means you can never write generic functions yourself
00:48
<inferno-cop>
Fair point.
00:48
<Welkin>
that is horrible
00:48
<Welkin>
you have a function you want to operate on Lists, and on Array, and on Map, and on etc.
00:48
<Welkin>
have to copy/paste it several times
00:48
<Welkin>
it's just stupid
00:48
<`Guest03>
Welkin: i never said that we don't need generic functions
00:48
<Welkin>
that is why Elm sucks
00:48
<Welkin>
at least one reaosn
00:48
<`Guest03>
i said that i need names for specialized versions too
00:49
<`Guest03>
defined in modules.
00:50
<Welkin>
`fmap :: (a -> b) -> [a] -> [b]` -- `Guest03 , done
00:50
<inferno-cop>
But at the same time, lists, arrays, maps, sets etc are all different in important ways, so writing generic implementations of algorithms for them would seldom be a good idea (if you care about performance)
00:50
<Welkin>
there is your specialized fmap for List
00:50
<`Guest03>
Welkin: too verbose
00:50
<`Guest03>
could just use L.map
00:50
<Jenaf>
I still have the feeling that I'm producing ugly code:
00:50
<Jenaf>
ieldReducer rows (a:(b:list))= (fmap (bfRowSetZeroPastN b) (Seq.take (b-a) rows))><(fieldReducer (Seq.drop (b-a) rows) (b:list))
00:50
<Welkin>
Jenaf: this ain't lisp
00:51
<pacak>
Jenaf: You are.
00:51
<Welkin>
Jenaf: paste it on lpaste and we can show you how to clean it up
00:51
<Jenaf>
I know but $ keeps throwing compilation errors
00:51
<lambdabot>
Haskell pastebin: http://lpaste.net/
00:51
<Welkin>
also, don't try to construct one big expression
00:51
<inferno-cop>
At least their should be a space on both sides of the equals sign :P
00:51
<Welkin>
break it up into smaller functions and use let/where clauses where they can help
00:52
<Jenaf>
in this case i think breaking it up into where would make it less readable
00:52
<Jenaf>
I've already broken down the main thingy into many subfunctions ^.^
00:53
<`Guest03>
blah @lpaste
00:53
<Jenaf>
http://lpaste.net/353365
00:54
<`Guest03>
could parse that, then user could mention lpaste and invoke command simultaneously
00:54
<Jenaf>
I'm quite sure I don't have the perfect representation of the Problem I want to tackle.
00:54
<MarcelineVQ>
`Guest03: it's bad form for a bot to guess what you intend, it tends to produce noise
00:54
<`Guest03>
that's bad if noise is very bad
00:55
<MarcelineVQ>
noise is very bad
00:55
<`Guest03>
it's not very bad for me...
00:55
<Welkin>
Jenaf: something more like this http://lpaste.net/353366
00:55
<Welkin>
but add type signatures to your functions
00:56
<Jenaf>
I think i always have signatures
00:56
<Jenaf>
thats what i start with when writin a function
00:56
<Welkin>
Jenaf: I see you are using list comprehensions in your code as well
00:56
<Welkin>
try to avoid those, especially for your use case
00:56
<Welkin>
just use a simple `filter` instead
00:57
<Jenaf>
can you tell me an example line?
00:57
<Jenaf>
(jsut line number)
00:57
<Jenaf>
also: I don't get <$>
00:57
<Welkin>
http://lpaste.net/353365#line121
00:57
<Welkin>
`<$>` is infix `fmap`
00:57
<Welkin>
you could also write it as `fmap` (literally with backticks)
00:57
<Welkin>
wrapping any function in backticks makes it infix
00:58
<Welkin>
<$> is specifically already defined as infix though
00:58
<Jenaf>
okay, so it's syntactical sugar
01:00
<Jenaf>
btw: those lists/sequences are only 9 elements long
01:00
<ReinH>
`` is syntax, <$> is a normal operator.
01:01
<Jenaf>
see line 70 for evil magic number code
01:01
<inferno-cop>
@src (<$>)
01:01
<lambdabot>
f <$> a = fmap f a
01:01
<Welkin>
Jenaf: I see a lot of unnecessary parentheses, but you'll get used to precedence rules with time
01:02
<Jenaf>
I tend to try and be better safe then sorry.
01:02
<Jenaf>
and soemtimes $ messes up at compliation/ loading in ghci
01:02
<Welkin>
the great thing about haskell is that you can afford to take risks
01:02
<Welkin>
if you mess up, the compiler will tell you
01:02
<Jenaf>
so I feel unsure about using $, but I know what parans do
01:02
<Welkin>
unlike other languages that fail at runtime
01:03
<Welkin>
$ is function application, but it has the lowest precendence
01:03
<inferno-cop>
I actually think $ often looks uglier than parentheses
01:03
<Jenaf>
like when you use gcc to compile C code with null pointers
01:03
<Welkin>
so it's like wrapping everything to the right-hand side of the $ in parens
01:03
defaultnick_ joined
01:04
robertkennedy joined
01:04
<Jenaf>
what I don't really like is stuff like
01:04
<Jenaf>
if isNothing squares
01:04
<Jenaf>
then Nothing
01:04
<Jenaf>
else Just $ foo (fromMaybe (error "unreachable") squares)
01:04
<Koterpillar>
Jenaf: this is fmap foo
01:05
<inferno-cop>
that can be rewritten!
01:05
<Welkin>
try to avoid using if-then-else
01:05
<Welkin>
it is not idiomatic and there are almost always better ways to write it
01:05
<Koterpillar>
> let foo = (* 2) in fmap foo (Just 3)
01:05
<Koterpillar>
> let foo = (* 2) in fmap foo Nothing
01:05
<lambdabot>
Nothing
01:05
<Welkin>
use pattern matching as much as possible
01:05
<Welkin>
and higher-order functions
01:05
<drostie>
What I like about $ is that a $ b $ c $ d is equal to a . b . c $ d.
01:06
<Welkin>
and yes, the Myabe Monad instance
01:06
<Koterpillar>
functor
01:06
<inferno-cop>
yup, your entire example can be rewritten: fmap foo squares
01:06
<Welkin>
er, Functor yes
01:06
<Welkin>
the Monad instance is very useful too though :P
01:06
<Koterpillar>
Jenaf: but if you want to go step by step, it's this:
01:07
<Koterpillar>
case squares of Nothing -> Nothing; Just value -> Just $ foo value
01:07
<Jenaf>
that should be äquivalent to the compiler?
01:07
<Jenaf>
(interpreted is a different story ofc)
01:08
<Koterpillar>
all three are equivalent
01:08
<Jenaf>
but that part with "fromMaybe (error "unreachable") foo" is really ugly
01:09
<inferno-cop>
Yeah, since you know that error "unreachable" is impossible to reach
01:09
<Jenaf>
so let mayList::Maybe[a]
01:09
<inferno-cop>
That's where you should use pattern matching
01:09
<Jenaf>
then I can fmap (foo:: a->b) mayList
01:10
<Koterpillar>
:t fmap
01:10
<lambdabot>
Functor f => (a -> b) -> f a -> f b
01:10
<Koterpillar>
replace f with Maybe
01:10
<mbw>
Ok the other day I asked for some advice about refactoring some data structures. It boiled down to introducing some more "helper types" in order to reduce overlap in constructor arguments. One of those subtypes was something like Helper a = None | A a | B b. I thought "None could be represented by Maybe" and made another type like Helper' a = A' a | B' b, and used it like Maybe (Helper' a). However, in
01:10
<mbw>
another function of type a -> Maybe a I introduced a very subtle bug because of this, when going from do notation to "clever Applicative style". So, and this is probably pretty opinionated, is there a lesson to learn from this? Should I try not to be overly clever with types, or stick to do notation? I often find myself "going back to a temporary do representation" when doing changes in functions using
01:10
<mbw>
applicative style, after all. Or is Maybe inside data structures generally a little dangerous because of cases like this?
01:11
<inferno-cop>
Jenaf: No, if you have mayList :: Maybe a, then you can do fmap (f :: a -> b) mayList :: Maybe b
01:11
<Jenaf>
okay i think i got that
01:12
<inferno-cop>
Jenaf: and that's the same as: case mayList of { Nothing -> Nothing; Just x -> Just (f x) }.
01:13
<Jenaf>
Memo to self: you always learn things and meet helpfull people at #haskell
01:13
<Jenaf>
thanks a lot ^.^
01:14
<inferno-cop>
So I heard! This is actually my first time ever using IRC :)
01:15
defaultnick___ joined
01:18
<stevenxl>
Hi folks. I'm reading Real World Haskell and I have to run ghc -c to compile a source file to object code.
01:18
<stevenxl>
Those directions seem to be out of date
01:18
<stevenxl>
What should I replace them with?
01:18
<ezyang>
what's the full snippet? ghc -c still works
01:19
<dunx>
stevenxl: man ghc
01:19
<dunx>
iirc -c works tho
01:19
<dunx>
did for me last time i was writing progs in haskell
01:19
<mbw>
stevenxl: Generally, the comments you can find on the online version of the books are very helpful.
01:20
<inferno-cop>
ghc -c works for me, just tested it
01:20
<mbw>
Most of the issues which arise from RWH being dated are adressed there.
01:20
<stevenxl>
mbw: online version you say?
01:20
<Jenaf>
I'm going to bed
01:20
<Jenaf>
see you later space cowboys
01:20
<stevenxl>
inferno-cop: weird. I am using stack so running `stack ghc -c Source.hs`
01:20
<mbw>
http://book.realworldhaskell.org/read/
01:21
<inferno-cop>
stevenxl: Ah, stack. I didn't try that
01:21
<stevenxl>
mbw: thank you!
01:21
<stevenxl>
inferno-cop: do I have the wrong program installed?
01:22
<stevenxl>
I see the -c option in `man ghc`. Stop after generating object file.
01:22
<mbw>
What are you using the object files for? I don't remember this from reading the book.
01:23
<stevenxl>
http://book.realworldhaskell.org/read/writing-a-library-working-with-json-data.html
01:23
<stevenxl>
mbw: the module is not set up to correctly generate an executable. missing the main function, etc.
01:23
<stevenxl>
i think i'm just going to brew install ghc and take it from there
01:24
<stevenxl>
mbw: See section Compiling Haskell Source if you're interested in the area I'm on.
01:24
<mbw>
Yeah I saw it.
01:25
<inferno-cop>
stack is good though, but I guess 'stack build' is meant to take care of build details...
01:27
<Welkin>
using homebrew to install ghc?
01:27
<Welkin>
sounds like a terrible idea
01:27
<Welkin>
just use stack or install from the bindist
01:27
<Welkin>
or use nix
01:28
<mbw>
stevenxl: Did you try stack exec -- ghc -c Source.hs? From my tab completion I don't see any -c command which could be passed to stack ghc.
01:29
<stevenxl>
mbw: I just tried that, and it work. Thank you!
01:32
<kit_>
Hey everyone, I'm running into a haskell problem that I can't figure out how to solve. Effectivley I'm trying to spawn a ghci process using createProcess, and then read and write to it but it keeps freezing or closing after about a minute
01:32
<sshine>
when I can do [ x | x <- [1..], x < 5 ], is that predicate strictly a list comprehension thing? I can't seem to write 'do { x <- [1..]; x < 5; return x }'
01:32
<kit_>
I think maybe the input and output handles are being closed but I have no idea how to avoid that, does anyone have any suggestions?
01:33
<teto>
what would be the best way to look for a string into a string plz ?
01:33
defaultnick__ joined
01:34
<mbw>
sshine: I think you need guard from Control.Monad.
01:35
<sshine>
teto, did you find http://stackoverflow.com/questions/8748660/is-there-a-better-way-to-write-a-string-contains-x-method ?
01:35
<sshine>
mbw, cool, thanks.
01:36
<teto>
sshine: I had found others but this one looks better thanks !
01:37
<Welkin>
sshine: use filter instead of list comprehensions
01:37
<Welkin>
> filter (< 5) [1..10]
01:37
<lambdabot>
[1,2,3,4]
01:38
<mbw>
teto: I don't think the question is really clear. Do you want to check if it exists? Or find it's position? Or... ?
01:38
<teto>
mbw existence is enough so I am good ty
01:39
markasoftware joined
01:40
halogenandtoast joined
01:40
<Welkin>
5 `isElem` [1..10]
01:40
<Welkin>
> 5 `isElem` [1..10]
01:40
<lambdabot>
Variable not in scope: isElem :: Integer -> [Integer] -> t
01:40
<sshine>
just `elem`, no?
01:40
<Welkin>
> 5 `elem` [1..10]
01:41
<* Welkin>
shakes fist at Elm
01:41
<Welkin>
still recovering
01:43
<mbw>
I have some expression like fun (Contructor a b c) = do { b' <- m b; return (Constructor a b' c) }. Is it possible to write this in Applicative style?
01:44
<Welkin>
that code doesn't make sense
01:45
<Welkin>
@undo { b <- mb; return b }
01:45
<lambdabot>
<unknown>.hs: 1: 1:Parse error: {
01:45
<Welkin>
@undo do b <- mb; return b
01:45
<lambdabot>
mb >>= \ b -> return b
01:46
<Welkin>
well, that is literally just fmap
01:46
<Welkin>
you could define fmap for your constructor
01:46
<Welkin>
for your mb
01:47
<Welkin>
whatever that is
01:47
<mbw>
I think I better paste an example.
01:49
<lyxia>
looks like a lens
01:50
<Koterpillar>
mbw: Constructor a <$> m b <*> pure c
01:53
<Zemyla>
What does it say about an Applicative type when a <* b = a and a *> b = b?
01:56
<ReinH>
that it's ()?
01:58
<mbw>
Koterpillar: That's the correct solution, thank you! Still, I pasted a minimal example of what my problem was about: http://lpaste.net/353369
02:02
<Koterpillar>
checkType (T s n m) = T s <$> check n <*> fmap check m
02:02
<mbw>
Koterpillar: Doesn't this correspond to checkTypeWrong?
02:02
<mbw>
This actually does not do the same thing.
02:03
<Koterpillar>
checkTypeWrong - no
02:03
<Koterpillar>
checkTypeWrong always has m as a Just something
02:03
<Koterpillar>
it is possible to have m = Nothing in my version
02:05
<mbw>
I do want it to treat the third argument like in the version using do notation, i.e. with pattern matching. From the program logic, if a Nothing is encountered, the other two values should still be able to "make it through".
02:05
<mbw>
If I try your version with Type "" 6 Nothing, it fails, but it shouldn't.
02:06
<mbw>
This kind of thing lead to a pretty subtle bug for me.
02:07
<Koterpillar>
> let check (x :: Int) = if even x then Just (x `div` 2) else Nothing in let checkType (x, y, z) = (,,) x <$> check y <*> pure (fmap check z) in checkType (1, 2, Nothing)
02:07
<lambdabot>
Just (1,1,Nothing)
02:07
<Koterpillar>
Back in your terms, checkType (T s n m) = T s <$> check n <*> pure (fmap check m)
02:07
the|auriscope joined
02:09
<`Guest03>
what does "Segmentation fault/access violation in generated code" mean?
02:09
<mbw>
This doesn't typecheck for me, the last term expands to Maybe (Maybe (Maybe Int)).
02:10
<augur>
lambdabot: ?faq can haskell make memes?
02:10
<lambdabot>
https://wiki.haskell.org/FAQ
02:10
<augur>
lambdabot: ?ask can haskell make memes?
02:10
<lambdabot>
Consider it noted.
02:13
<Koterpillar>
mbw: suggest changing check to Either, then the type errors will be obvious
02:13
<Koterpillar>
or anything other than Maybe, really
02:14
<`Guest03>
oh welllll....
02:14
<`Guest03>
shaderSource (from the OpenGL binding) segfaults my program if the source text is empty...
02:16
<mbw>
Koterpillar: I'm using Maybe in the context of symbolic manipulations on algebraic expressions, which can become zero under certain circumstances, so it was an alright fit in this case.
02:17
<mbw>
I think I will just stick with the version using do notation, for readability.
02:19
exferenceBot joined
02:20
<mbw>
Anyhow, thanks for your help!
02:24
<echosystm>
what sorts of applications is haskell most suited to, given its performance, libraries, etc?
02:24
<markasoftware>
echosystm: it's a g8eneral purpose language
02:24
<echosystm>
i understand that
02:24
<echosystm>
but in the real world, what is it most useful for compared to other languages?
02:25
<markasoftware>
depends if you like it or not
02:25
<markasoftware>
i'd say it's easier to define what it's not so great at: guis
02:26
<echosystm>
ok let me put it another way
02:26
<echosystm>
what is haskell most used for?
02:26
<markasoftware>
what is python most used for?
02:26
<echosystm>
cultivating neckbeards
02:27
<markasoftware>
it's not "most used" for any one thing
02:27
<markasoftware>
or any group of things
02:27
<echosystm>
swift - ios, ruby - web apps, java - enterprise stuff, etc.
02:27
<echosystm>
every language has some main purpose that has come about over time
02:27
<markasoftware>
that's definitely not correct right there
02:27
<c_wraith>
Haskell is easily most used for writing software
02:27
<markasoftware>
apart from swift - ios
02:28
<c_wraith>
it has some other minor uses.
02:28
<markasoftware>
ruby existing long before ruby on rails
02:28
<c_wraith>
but it's definitely for building software
02:28
<echosystm>
yeah but almost all ruby devs use rails lol
02:28
<ertes>
echosystm: haskell is not suitable for targetting small/embedded systems directly
02:28
<pikajude>
haskell is good for frightening people
02:28
<markasoftware>
well that's what it's turned into after a while
02:28
<markasoftware>
but haskell wasn't designed for any one purpose like Javascript was
02:28
<echosystm>
neither was ruby, but ruby == rails now
02:28
<markasoftware>
or php
02:29
<c_wraith>
if you want to get really narrow, Haskell's best niche is software that's maintained.
02:29
<ertes>
echosystm: other than that i can't think of anything i wouldn't pick haskell for
02:29
<echosystm>
so, as an fp newbie, i just want to know what box i can put haskell into
02:29
<ertes>
echosystm: if you ask 10 people, you will get 10 different answers… you should just try it
02:30
<c_wraith>
@quote used.for
02:30
<lambdabot>
fasta says: Haskell is like an efficient version of Python and is used for the same things.
02:30
<c_wraith>
hmm, that's not the one I was looking for
02:30
<ertes>
@quote HashMap
02:30
<lambdabot>
ertes says: python can be summarised as HashMap String Dynamic
02:30
<markasoftware>
echosystm: you can't put C, python, java, or totns of other languages into a "box"
02:30
<markasoftware>
haskell either
02:30
<markasoftware>
they're very general purpose lanugages
02:30
<markasoftware>
php was designed with a purpose -- servers
02:30
<markasoftware>
js was for front end web scripting
02:31
<markasoftware>
sql for querying databases
02:31
<markasoftware>
haskell -- no
02:31
<ertes>
echosystm: one thing haskell is particularly strong at is concurrency, especially for networked stuff like servers and clients… it's also strong at processing lots of data (but you need to learn how to do it properly)
02:32
<ertes>
it's strong at embedded domain-specific languages, if that means anything to you
02:32
<c_wraith>
Haskell is quite successfully used for live-coding music performances
02:34
<c_wraith>
Haskell is also excellent for studying the application of mathematical structures to programming.
02:34
<echosystm>
i disagree markasoftware
02:34
<c_wraith>
but mostly, it's used for writing software.
02:34
<echosystm>
i think C, python and java do have fairly clear uses
02:34
<echosystm>
but anyway
02:34
<ertes>
or live-coding in general… i've used a small lens-based library for live-coding at a crypto workshop several times (often quite literally with a few jaw-drops)
02:34
<markasoftware>
what exactly is C's single use case?
02:35
<echosystm>
it sounds like systems programming would be a pretty common use for haskell
02:35
<echosystm>
probably comparable to the sorts of projects i'm using go for currently
02:35
<markasoftware>
or java or python for that matter
02:35
<markasoftware>
all three of those have been used for all sorts of major projects that are very different
02:36
<markasoftware>
java has been used for mobile apps, desktop games, giant databases (cassandra), servers, etc etc
02:36
<ertes>
echosystm: i've observed a lot of haskell programmers trying to bring everything into haskell-land, often rewriting haskell versions of libraries from scratch to do it (myself included)
02:37
<ertes>
so it's really difficult to decide what you will be using haskell for, until you have actually learned it to some extent
02:38
<c_wraith>
ertes, lens makes a lot of live-coding jaw-dropping. like, lens-aeson makes live json manipulation astounding. and I had a demo of using lenses to examine a full game tree for tic-tac-toe in a live setting.
02:39
<ertes>
c_wraith: my use case was stuff like: textFiltered isAlpha . blocks 3 . ix 0 . letter +~ 13
02:39
<ertes>
i.e. rotate every third *letter* by 13 places
02:40
<ertes>
the jaw-drop effect kicks in as soon as you use traversals =)
02:40
<peddie>
c_wraith: is there a screencast of any of these available?
02:40
<ertes>
or non-field lenses like textFiltered (lens into a filtered portion of the text)
02:40
<c_wraith>
peddie, no. best I can do is find the code that created the game tree and lenses for working with it.
02:41
<peddie>
no worries
02:41
<MarcelineVQ>
what do you two mean by live coding?
02:41
<Gurkenglas_>
Try to do screen recordings the next time, or stream it on a website like livecoding.tv
02:41
<ertes>
MarcelineVQ: in my case: sitting in front of an audience with a beamer and hacking stuff into emacs/GHCi
02:42
<c_wraith>
MarcelineVQ, setting up some tools and then use them interactively to try things based on the result of previous exploration.
02:42
<c_wraith>
MarcelineVQ, usually in a REPL
02:43
<hololeap>
when you use record syntax with one argument of a constructor, do you have to use it for all arguments of the constructor?
02:44
<ertes>
hololeap: only when using the constructor rather than an existing value in scope
02:44
<MarcelineVQ>
ertes, c_wraith: thank you
02:45
<ertes>
@let data Person = Person { _numFingers :: Integer, _numTeeth :: Rational } deriving (Eq, Ord, Show)
02:45
<lambdabot>
Defined.
02:46
<hololeap>
for instance `data Iterator a = a {nextLevel :: Iterator a}` gives me "Record syntax is illegal here", but `data Iterator a = {iterItem :: a, nextLevel :: Iterator a}` is ok
02:46
<Axman6>
that doesn't look ok
02:46
<geekosaur>
hololeap, yes it's all or nothing and it must have a constructor
02:46
<ertes>
@let dentist x = x { _numTeeth = 32 }
02:46
<geekosaur>
a is not a constructor
02:46
<lambdabot>
Defined.
02:46
<ertes>
> dentist (Person 10 17.4)
02:46
<lambdabot>
Person {_numFingers = 10, _numTeeth = 32 % 1}
02:47
<hololeap>
sorry, i mistyped that: `data Iterator a = Iterator {iterItem :: a, nextLevel :: Iterator a}`
02:47
<geekosaur>
and even wth the constructor, you must use either the positional or the record syntax, you can't switch in the middle
02:48
<geekosaur>
although you can do something like data Foo a = Foo1 a | Foo2 {aa :: a; ab :: Int}
02:48
<geekosaur>
(but don't do that, partial record destructors will throw exceptions if used against the wrong constructor)
02:49
<izacht13>
Hi, can someone point me in the right direction. I'm looking for a monad lesson that goes over the concept, not the syntax. I'm trying to learn Ur/Web, which also has monads.
02:49
<geekosaur>
tht is, if you apply aa or ab to a Foo1 then it will throw
02:49
<geekosaur>
@go you could have invented monads
02:49
<lambdabot>
Maybe you meant: google googleit do
02:49
<geekosaur>
@google you could have invented monads
02:49
<lambdabot>
http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html
02:49
<lambdabot>
Title: A Neighborhood of Infinity: You Could Have Invented Monads! (And Maybe You Al...
02:49
<ertes>
izacht13: if there is no ur/web-related version, you will most likely see haskell syntax anyway
02:50
<izacht13>
Mhm, well thanks.
02:50
<izacht13>
Ill take a look at it.
02:50
<geekosaur>
it'll still have syntax, but it's mostly bout the concept
02:50
<ertes>
or at least the haskell-based ones are probably the most trustworthy
02:50
<geekosaur>
several examples of evolving the monad "pattern" from various use cases
02:51
<leshow>
man lambdabot is pretty sweet, i had no idea you could search google with it
03:02
<ertes>
lambdabot has far more impressive feats than that
03:03
<ertes>
@djinn ((a -> r) -> r) -> (a -> (b -> r) -> r) -> (b -> r) -> r
03:03
<lambdabot>
f a b c = a (\ d -> b d c)
03:06
<faberbrain>
can anyone give me some ideas about how to accomplish something along these lines: http://lpaste.net/5129458430632787968
03:07
<faberbrain>
specifically, for a given j, queueName should basically be a constant
03:07
<ertes>
faberbrain: you need to mention 'j' in the type… a common method is to use a proxy argument
03:08
<ertes>
queueName :: proxy j -> ByteString
03:08
<faberbrain>
ok yea, i started going down that path
03:08
<faberbrain>
but wasn't sure if there was some simpler kind of way to do that
03:08
<pikajude>
not much simpler than that
03:09
<ertes>
faberbrain: import Data.Proxy, queueName (Proxy :: Proxy MyJobType)
03:09
<faberbrain>
guess that is pretty simple
03:09
<ertes>
faberbrain: also take a look at the aeson library, which already covers the first two functions
03:10
<ertes>
class (FromJSON j, ToJSON j) => Resque j where queueName :: proxy j -> ByteString
03:10
<faberbrain>
yea, i'm using aeson and may just add a FromJSON/ToJSON constraint
03:10
<faberbrain>
but the particular JSON required by Resque (the ruby queueing library) is so weird that i may want it to e an alternative json represnetation
03:11
<ertes>
faberbrain: you can make the JSON look like anything you want
03:12
<faberbrain>
yea, i was more thinking along the lines of what if i don't want the Resque-json to be _the_ json representation for the data type.. but thinking on it more thats kinda dumb maybe
03:12
<faberbrain>
since thats the only point of that data tyep in the first place
03:12
<ertes>
faberbrain: same kind of question: is Integer the (+) or the (*) monoid? answer: use a newtype wrapper to select different semantics
03:13
<ertes>
> Sum 5 <> Sum 7
03:13
<lambdabot>
Sum {getSum = 12}
03:13
<ertes>
> Product 5 <> Product 7
03:13
<lambdabot>
Product {getProduct = 35}
03:13
<faberbrain>
ok yea, makes sense
03:13
<pikajude>
> mempty @(Product Int)
03:13
<lambdabot>
Pattern syntax in expression context: mempty@(Product Int)
03:13
<lambdabot>
Did you mean to enable TypeApplications?
03:13
<faberbrain>
so its more conventional to newtype wrap something then come up w/ some arbitrary new alternative thing (like an alternative to/from json)
03:14
<ertes>
faberbrain: yes, because you're not looking for a different abstraction, just different semantics with an existing abstraction
03:15
<ertes>
(+) and (*) *are* both monoids
03:15
<ertes>
so it would be crazy to make (+) the default and invent a new monoid class to handle (*)
03:16
<ertes>
along with all the functions that abstract over Monoid, like foldMap
03:16
<faberbrain>
yea, i see.. thats a good way to think about it
03:16
<faberbrain>
(probably _the_ way to think about it, i just hadn't reached that myself yet!)
03:17
<faberbrain>
thanks!
03:18
<ertes>
faberbrain: of course nothing wrong with making a particular semantics the default and selecting different ones via newtype
03:19
AndChat61364 joined
03:19
<ertes>
like: clean JSON as default, insane JSON via newtype
03:19
the|auriscope joined
03:19
<faberbrain>
yea and in this case there honestly is really only one meaning, there isn't ever a need for a clean JSON rep (yet i guess)
03:20
<faberbrain>
so probably makes sense to do the insane json as the default, since its the common use case
03:20
<ertes>
insane JSON is quite common… perhaps aeson should provide a wrapper by default
03:20
<athan>
is @ just... ::?
03:21
<athan>
I don't really see how they differ semantically :s
03:21
<pikajude>
kind of, not really
03:21
<pikajude>
if you have foo :: a -> b -> c you can use @T to fill in the variables
03:21
<Koterpillar>
:t fmap@Maybe
03:21
<pikajude>
Proxy :: Proxy Int --> Proxy @Int
03:21
<lambdabot>
Pattern syntax in expression context: fmap@Maybe
03:21
<lambdabot>
Did you mean to enable TypeApplications?
03:21
<pikajude>
bit shorter
03:21
<pikajude>
lambdabot doesn't have them enabled
03:22
<ertes>
athan: if you look at the fully quantified type signature @ will apply type variables as introduced by 'forall'
03:22
<ertes>
id :: forall a. a -> a
03:22
<pikajude>
it's helpful to turn on ExplicitForall in GHC btw
03:22
<pikajude>
or rather GHCi
03:22
<ertes>
(id @ Bool) :: Bool -> Bool
03:22
<pikajude>
or wait, sorry, i'm completely wrong
03:22
<pikajude>
it's -fprint-explicit-foralls
03:22
FjordPrefect joined
03:22
<ertes>
athan: so @ is literally application and therefore not the same as "::", which is more like a judgement
03:23
<ertes>
athan: think about it this way: if haskell were dependently typed, "@" would literally be function application
03:33
<athan>
ertes, pikajude: Ahh wow okay that makes sense, so @ treats `forall` as a proper lambda?
03:34
<athan>
man that makes a lot of sense, thank you
03:34
<athan>
:: as a judgement, and how Curry works, that would also make a lot of sense too (ziiiing)
03:40
uglyfigurine joined
03:44
whatinthefoo joined
03:45
<whatinthefoo>
Hi, I'm reading the happy parser docs and I came across this code: http://lpaste.net/353374
03:45
<whatinthefoo>
lexer is defined as accepting one argument... but the pattern matches 2 arguments ??
03:46
<whatinthefoo>
When I try similar code in haskell locally I get an error... is this an issue with the happy docs or am I missing something?
03:47
<Koterpillar>
whatinthefoo: what's P?
03:47
<whatinthefoo>
Koterpillar: P is 'type P a = String -> ParseResult a'
03:47
<geekosaur>
that's your answer
03:48
<geekosaur>
P a represents a function
03:48
<whatinthefoo>
huh?
03:48
<whatinthefoo>
okay
03:48
<whatinthefoo>
I know that part
03:48
<geekosaur>
so cont is a function that produces a function
03:48
<geekosaur>
the "result type" P a is also a function
03:48
<whatinthefoo>
'lexer :: (Token -> P a) -> P a; lexer cont s = '
03:48
<geekosaur>
so you can apply it, and the "s" parameter is applied to it
03:49
<whatinthefoo>
how can you do 'lexer cont s =' though?
03:49
<geekosaur>
let's try this: expand the P a in the type of lexer
03:49
<geekosaur>
then remember that you can remove parens grouping rightward
03:49
<geekosaur>
(Token -> P a) -> (String -> ParseResult a)
03:50
<geekosaur>
we can remove the last parentheses
03:50
<geekosaur>
(Token -> P a) -> String -> ParseResult a
03:50
<geekosaur>
there's your cont and your s
03:50
<whatinthefoo>
ohhh
03:50
<geekosaur>
it's one of the trickier things to get used to in Haskell
03:52
<whatinthefoo>
that makes sense
03:52
<whatinthefoo>
i kept thinking that the P a in (Token -> P a) was being pattern matched somehow
03:54
<lambdabot>
(a -> b) -> [a] -> [b]
03:54
<geekosaur>
we do the same thing in reverse here, fairly often
03:54
<geekosaur>
(a -> b) -> ([a] -> [b])
03:54
<geekosaur>
turning a function on a into a function on lists of a
03:55
exferenceBot joined
03:55
<xmonader>
is there a special meaning to colon in the beginning of line comments in haskell "--:" ?
03:55
<whatinthefoo>
thanks geekosaur
03:56
<xmonader>
because i get "parse error on input ‘--:’"
03:56
<geekosaur>
xmonader, it's not a comment
03:56
<geekosaur>
--: is a valid operator name
03:56
<geekosaur>
-- is only a comment leader when followed by something that is not a symbol character
03:57
<geekosaur>
so --<space> or --a would be a comment but --: is an operator
03:57
<xmonader>
uha I see. Thanks a lot geekosaur
03:57
<geekosaur>
likewise you'll see --> as an operator in some libraries
03:59
<cc>
may i get a haskell cloak ?
04:09
<suica>
anyone have a nice way of doing something like, given a string like `"(()())()"`, breaking it into `["(()())", "()"]` by counting matching parens (or any similar operation where you unfold into a list by keeping a running count and breaking off a piece right after the count reaches zero)?
04:09
<suica>
could do it with zip, map, fst, snd, etc. but was wondering if anyone had a more concise way
04:17
<ludat>
suica, what should happen with corner cases not matching parens?
04:21
<suica>
i was going to ignore them
04:22
<suica>
i just had a feeling there are some combinators or something I could use instead of doing a bunch of stuff like `break (f . snd) (zip (map nestLevels xs) xs)`
04:23
<suica>
i'll try lambdabot
04:27
<lyxia>
> let s = "(()())()" in (fmap . fmap) snd $ groupBy (const ((/= 0) . fst)) $ zip (scanl (+) 0 (f s)) s
04:27
<lambdabot>
• Ambiguous type variable ‘a0’ arising from an operator section
04:27
<lambdabot>
prevents the constraint ‘(Eq a0)’ from being solved.
04:28
<lyxia>
Oh I forgot to paste in f.
04:30
<lyxia>
> let s = "(()())()" in (fmap . fmap) snd $ groupBy (const ((/= (0 :: Int)) . fst)) $ zip (scanl (+) (0 :: Int) (fmap (\x -> case x of '(' -> 1 ; _ -> -1) s)) s
04:30
<lambdabot>
["(()())","()"]
04:30
uglyfigurine joined
04:30
<lyxia>
that's not simpler than just recursing
04:30
<suica>
yeah, fair enough
04:32
<suica>
i've just been reading a lot of the "recursion is the goto of functional programming" stuff recently and wanted to try out some fancy things
05:11
<skeuomorf>
Is the overloadedstrings language pragma documented anywhere?
05:14
<jle`>
skeuomorf: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#overloaded-string-literals
05:14
<jle`>
in the ghc manual
05:14
<markasoftware>
skeuomorf: there's some stuff about it in the introduction chapter of the yesod book
05:14
<markasoftware>
which was enough for me to (mostly) understand it
05:15
<skeuomorf>
jle`: Thanks
05:22
<lolisa>
Hi, I am having some problem with my haskell code, I suspect it might be a bug: is it possible that splitting a file in two cause a term to inference different typeclass constraint?
05:23
<ertes>
lolisa: one way this can happen is if you forget to turn on the same extensions in both files
05:23
<ertes>
another way: different imports, different things in scope
05:24
<ertes>
for example, if you import Control.Monad.Trans.State in one and Control.Monad.State in the other
05:26
<lolisa>
Hmm, I indeed have different lang extension.
05:27
<lolisa>
OMG now it work
05:27
<lolisa>
ertes, Thx, bugging me for three hour... Where can I read more on such stuff?
05:28
<ertes>
lolisa: the GHC manual explains what each extension does
05:28
<ertes>
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/index.html
05:28
<ertes>
they are a bit scattered around, so ctrl+f is your friend
05:29
<ertes>
(or / or C-s or …)
05:32
<Suren>
What's up lolisa, are you a Haskell developer just having a chat or are you new to the language?
05:37
<lolisa>
Suren, I dont know, but shouldnt we like, talk more about haskell stuff instead of individual?
05:38
<peddie>
lolisa: there is also a guide to some common GHC extensions at https://ocharles.org.uk/blog/pages/2014-12-01-24-days-of-ghc-extensions.html
05:40
<KiChjang>
Suren, i happen to be new at the language
05:40
<KiChjang>
i know zilch
05:40
<Suren>
I was just asking you that question to see if you are the right person to ask my real question to, which is; as a web developer why would I choose haskell for a project over let's say C# .NET MVC
05:41
<KiChjang>
Suren, i think the answer here is you would not
05:41
<lambdabot>
Unknown command, try @list
05:41
<KiChjang>
haskell isn't the right tool for that job i believe
05:41
<Suren>
Why do you say that?
05:41
<lolisa>
I'm here. Dont know about web, sorry.
05:41
<KiChjang>
if you're using C# .NET MVC, then you're most likely making a web application
05:42
<Koterpillar>
My .Net knowledge is rusty, but I would choose Haskell anyway
05:42
<Suren>
What applications is haskell good for?
05:42
<KiChjang>
literally "rusty" or "rust-y"?
05:42
<ertes>
hackage has more web frameworks than TYPO3 has global variables
05:42
<Koterpillar>
because why would I give away referential transparency?
05:42
<ertes>
so it's a weird thing to say
05:42
<KiChjang>
Suren, i would consider it more of an academic language
05:42
<Koterpillar>
Suren: applications where you want correctness
05:43
<pacak>
Suren: parsing, ast manipulation
05:43
<KiChjang>
there was a blog post before that talks extensively about how a company used haskell in production
05:43
<pacak>
We are using it for automated trading.
05:43
<KiChjang>
lemme try and fish that up
05:44
<Suren>
Pacak: Automated trading has always interested me, how did you get into the field? What was your background before that job?
05:45
<pacak>
Suren: Submitted my application. Had relatively basic haskell experience, no finance background.
05:46
<Suren>
Pacak: How many years into your software engineering career were you? Did you have a CS or Stem degree? Was it from a top university?
05:46
<KiChjang>
Suren, btw, this happened a while ago in #haskell but may also be relevant https://gist.github.com/quchen/5280339
05:47
<Suren>
KiChjang: thanks
05:47
<KiChjang>
(probably not but eh, good for laughs)
05:47
<pacak>
Suren: I've been developing various stuff for quite a while back then. No CS, no fancy university either.
05:49
<Suren>
Pacak: Nice man, really glad to hear! I'm a self-taught developer without a degree, about a year into my career now. I always hoped for a career in finance software engineering but didn't think it was possible without a CS degree.
05:52
<buttons840>
I am seeing "Type as Type" in an error -- what exention is this?
05:52
<buttons840>
extension*
05:53
<jle`>
can you give the context?
05:53
<jle`>
is Type as Type the error message?
05:54
<buttons840>
"Couldn't match expected type Text with actual type HVec as Text" -- something like this
05:55
<jle`>
i think 'as' is a type variable there
05:55
<jle`>
you are giving a value of type 'HVec bs Text', but the function expects a Text
05:55
<buttons840>
jle`: you are right, it's actually "as0"
05:56
<buttons840>
so, in spocks renderRoute (https://hackage.haskell.org/package/Spock-0.12.0.0/docs/Web-Spock.html#v:renderRoute) the "as" is a type variable?
05:57
<buttons840>
it's not colored like a type variable, guess it's just a css issue?
05:57
<jle`>
it's colored as a type variable on my browser
05:58
<jle`>
it's just plain black text
05:58
<jle`>
looking at the HTML, type variables don't have any specific styles
05:59
<buttons840>
ah, your right, it's rendered the same as all other type varibles -- i guess it's just that it was sitting between two links that threw me off
06:16
<lolisa>
Hi, so I do cabal install hscolour, but I still cant run the command (or use it from cabal). I am using windows, what should I do?
06:17
<Axman6>
you probably need to add the install location to your path, but I have no idea how to do that on windows
06:19
<Axman6>
lolisa: this looks like it nas what you need: http://stackoverflow.com/questions/15461085/how-to-configure-cabal-in-windows-7
06:29
<lolisa>
Axman6, thx
06:36
<halogenandtoast>
If I'm considering making a static website is Hakyll a good way to go?
06:36
<Axman6>
it's not a bad way to go, I use it for my website
06:37
<halogenandtoast>
https://axman6.com/blog/ ?
06:37
<Axman6>
that's the one
06:37
<halogenandtoast>
That page isn't selling me :p
06:37
<Axman6>
uh, actually without /blog IIRC
06:37
<halogenandtoast>
Ah much better
06:37
<Axman6>
not even sure how that page is being served...
06:37
<Axman6>
it shouldn't even be there :|
06:38
<halogenandtoast>
Your github links there
06:38
<halogenandtoast>
Which is why I ended up there
06:38
<Axman6>
I'll fix that
06:39
<halogenandtoast>
Ha nice, are there any particular tools you suggest?
06:40
<Axman6>
btw I believe that the code for my site is also on github
06:40
<Axman6>
https://github.com/axman6/axman6.com
06:40
<halogenandtoast>
Ah sorry I meant things you found useful to use with Hakyll
06:40
<Axman6>
the important bits are in site.hs
06:41
<halogenandtoast>
Cool thanks, I'll check it out.
06:41
<pikajude>
blog posts need a bit more contrast
06:41
<pikajude>
i can barely read it
06:41
<Axman6>
submit a PR =)
06:42
<lolisa>
Hi... the problem is still there, so basically if you move Poly into DBI, it will compile, but right now it wont. Can anyone look at it? I am working on a minimal example.
06:42
<lolisa>
https://github.com/ThoughtWorksInc/DeepDarkFantasy/tree/master/src
06:43
<pikajude>
oh, no, i don't want to contribute to your blog
06:43
<pikajude>
this is just my opinion as a reader
06:44
<halogenandtoast>
pikajude: My life rule has always been to never complain about something I won't try to fix myself :p
06:44
<halogenandtoast>
Not judging you, just saying
06:44
<pikajude>
my life rule has been not to try to interfere with other people's possessions
06:45
<halogenandtoast>
Must make it hard to get a house or car loan.
06:45
<pikajude>
i have neither
06:45
<halogenandtoast>
Story checks out.
06:49
uglyfigurine joined
06:52
ragepandemic joined
07:00
<lolisa>
I got the minimal example out. So as you can see, https://github.com/ThoughtWorksInc/DeepDarkFantasy/blob/master/src/PolyT.hs contain a definition that is included in https://github.com/ThoughtWorksInc/DeepDarkFantasy/blob/master/src/DBIT.hs (but under different name), but wont type check
07:00
<lolisa>
No library is used, and they have same language extension
07:08
<qmm>
12:30 < c_wraith> Experiments with per-process GC for GHC have shown it to not be especially compatible with laziness.
07:08
<qmm>
c_wraith: do you have links, paper titles, email subjects, or any keywords to share whatsoever about this?
07:09
<qmm>
i am still interested in this subject
07:09
<c_wraith>
there was a paper by at least one of the simons about adding per-HEC heaps
07:09
<c_wraith>
I don't recall the name of it
07:14
<qmm>
c_wraith: ah okay. i'm aware
07:15
<qmm>
it added something like 15% performance increase and according to #ghc it wasn't easy to implement so it was never merged
07:15
uglyfigurine joined
07:15
<qmm>
i read per-HEC has per core heaps
07:15
<qmm>
what is HEC? :)
07:16
<qmm>
haskell execution context, i see
07:17
<qmm>
c_wraith: thank you
07:17
<c_wraith>
oh hey. the paper was by both simons. :)
07:18
<qmm>
http://community.haskell.org/~simonmar/local-gc.pdf
07:18
<qmm>
haskell doesn't sound like it's desirable for distributed programming type projects
07:19
<qmm>
<-- noob in distributed computing
07:22
<c_wraith>
I don't think it's inherently unsuitable, just that there's a lot of engineering work that hasn't been done
07:23
<qmm>
the lightweight scheduler work would be a nice first step
07:26
<Rotaerk>
isn't that what cloud haskell is for?
07:27
<qmm>
cloud haskell mimics erlang's style concurrency without changing the haskell runtime
07:27
<qmm>
erlang style concurrency
07:27
<qmm>
it's a library, in other words
07:29
uglyfigurine joined
07:29
<ongy>
Axman6: I've read your blog article about linear typing, do you know how much that would change if ghc got some support for it?
07:31
<qmm>
ongy: thanks for mentioning that Axman6 has a blog (and a post about linear types!)
07:55
uglyfigurine joined
07:59
magneticduck joined
08:03
<ongy>
Axman6: I hope you don't mind if I rip off your website a bit, when I decide to blog something at any point. I like the design
08:08
uglyfigurine joined
08:10
curious_corn joined
08:34
uglyfigurine joined
09:14
uglyfigurine joined
09:24
caumeslasal1 joined
09:53
uglyfigurine joined
10:09
uglyfigurine joined
10:15
andrei_chifa joined
10:16
<Athas>
Has anyone studied the performance impact of using deepseq?
10:20
<srhb>
Athas: What do you mean? Deepseqing what and when?
10:21
<Athas>
srhb: deepseq'ing involves traversing an entire object graph, right? I see it frequently used in (task-)parallel Haskell code, to ensure that the computation is actually done in worker threads before the result is passed back to a main thread.
10:22
<Athas>
I'm curious whether the traversal in deepseq can have a significant negative performance impact.
10:22
<Athas>
Looks to me like it can easily evict the entire cache.
10:29
<merijn>
Athas: It can also do a bunch of unnecessary work, so the obvious answer is "yes" ;)
10:30
<Athas>
merijn: okay, but has anyone studied it? Things like monad-par seem to be quite happy about implicitly deepseq'ing anything you put in a future, which may have an impact in some cases.
10:31
<Athas>
There's been a lot of work on Haskell parallelism and performance, after all.
10:31
<merijn>
Honestly, if evicting caching is something you worry about, I don't think Haskell is an ideal language to begin with
10:31
<merijn>
laziness is pretty crappy for your caches
10:32
SolitaryCypher joined
10:33
uglyfigurine joined
10:33
<Athas>
Well, you could use laziness for control flow.
10:34
<Athas>
I'm mostly asking because I don't know the answer, but lots of smart people have been working on it for years.
10:34
<merijn>
Athas: I don't think anyone knows, tbh
10:35
<Athas>
"High-performance", "functional", or "programming", pick two?
10:35
<merijn>
Athas: There's a guy at Twente working on designing a CPU for lazy languages, so I know he's thought about caches and stuff (mostly, he said he decided not to use caches in the traditional sense), but I'm not sure if he has a write up on that
10:35
<Athas>
That sounds cool! Lazy and pure, or impure?
10:35
<merijn>
Athas: Purity is rather irrelevant at the chip level
10:36
<Athas>
Right, but you could call the total absence of cache coherence "purity".
10:36
<merijn>
At the CPU level you're thinking about thunk updating, indirection, etc.
10:39
<Boomerang>
merijn: is that CPU for lazy languages being written in CLaSH?
10:40
<merijn>
Boomerang: He's in the same group as the CLaSH people
10:40
<Boomerang>
Alright! Is it possible to read about this CPU somewhere online?
10:41
<merijn>
Boomerang: But since the project I was collaborating on ended a while back I only see them incidentally, so I'm a bit out of date
10:41
<Boomerang>
It sounds very interesting, I would love to find out more about it
10:41
<merijn>
Boomerang: It doesn't exist yet, even in design, afaik :p Now would only be like the 2nd year of his phd?
10:42
<Boomerang>
Fair enough :)
10:48
uglyfigurine joined
10:48
<merijn>
Boomerang: I expect I'll run into them later this month, so I'll ask them about it
11:02
<_sras_>
Is there a type class in haskell that can be used to describe conversions between related types?
11:02
<Athas>
_sras_: not a standard one, no.
11:06
<Boomerang>
_sras_: You could look at how opaleye does it to convert between Haskell type and SQL specific types, the type class used it called Default. I don't understand it fully but it seems to be what you want.
11:06
<_sras_>
Boomerang: 'Default Constant' instances describes conversion in one direction...
11:07
<Athas>
And be prepared for ambiguity errors...
11:10
<Boomerang>
_sras_: Ah yes, I am not aware of a standard way to do this, you could just create your own type class then
11:14
<Boomerang>
_sras_: Again I don't really know this package but would the Bijection type class from invertible be useful? It's a bidirectional arrow. It seems appropriate to convert a type from and to another one
11:14
<_sras_>
Boomerang: Will look into it. I am not familiar with it either.
11:19
<otulp>
Yikes. Just saw the (=<<->>=) operator in Data.Invertible.Monad. Its description: "Crazy operator form of bind." :)
11:30
<cocreature>
that definitely qualifies as crazy
11:32
<Boomerang>
At least it reuses well known infix symbols, but yeah that's a crazy operator
11:34
JeanCarloMachado joined
11:35
netheranthem joined
11:38
<Athas>
I wonder what's the largest operator name on Hackage.
11:39
<otulp>
Surely there is something hideous somewhere in the Acme hierarchy.
11:43
surelyourejoking joined
11:47
<Jenaf>
good morning!
11:47
<Taneb>
Athas, https://gist.github.com/ndmitchell/aa1e0944379a7429cedb#file-gistfile1-txt
11:47
<Jenaf>
Yesterday I was told to better replace if then else constructs with case matchings
11:47
<Jenaf>
also i have some unreachable code in a fromMaybe wich is guaranteed not to be nothing
11:48
<Jenaf>
http://lpaste.net/353382
11:48
<Jenaf>
any tipps how to write that more cleanly?
11:49
<Athas>
Taneb: thanks; some good ones there!
11:49
<otulp>
I see functor-infix is doing quite well, lengthwise.
11:50
reverse_light joined
11:50
<Jenaf>
I would love to get rid of this : fromMaybe (error "unreachable")
11:50
<Taneb>
Jenaf, is fromJust an option?
11:51
<Taneb>
> fromJust (Just "hello")
11:51
<lambdabot>
"hello"
11:51
<Jenaf>
> fromJust (Nothing)
11:51
<lambdabot>
*Exception: Maybe.fromJust: Nothing
11:51
<ongy>
Jenaf: if it's not reachable why is the argument of type (Maybe Int) ?
11:51
<Athas>
Jenaf: 'sequence mayList' will give you a 'Maybe [Int]' back.
11:51
<Athas>
You can pattern-match on that, instead of the branch.
11:52
<Taneb>
> [x | Just x <- [Just 1, Nothing, Just 2, Just 3, Nothing]
11:52
<lambdabot>
<hint>:1:58: error:
11:52
<lambdabot>
parse error (possibly incorrect indentation or mismatched brackets)
11:52
<Taneb>
> [x | Just x <- [Just 1, Nothing, Just 2, Just 3, Nothing]]
11:52
<ongy>
that and I think you can use the Monad and MonadFail instances of Maybe here
11:52
<lambdabot>
[1,2,3]
11:53
<Athas>
> sequence [Just 1, Just 2, Just 3]
11:53
<lambdabot>
Just [1,2,3]
11:53
<Athas>
> sequence [Just 1, Just 2, Just 3, Nothing]
11:53
<lambdabot>
Nothing
11:53
<Jenaf>
I stay with maybe because i get the values from a sequence findIndexL
11:54
<ongy>
yea, I wasn't properly reading at first, I thought it's Maybe [Int] which was weird, but [Maybe Int] is a bit different
11:54
<Boomerang>
> catMaybes [Just 1, Nothing, Just 2]
11:54
<Jenaf>
in the bigger context Nothing means that my propblem is unsolvable, while values indicated that the program can go on solving
11:55
<Jenaf>
so I will propably have a case X of Nothing -> Nothing //of Just something -> foo(something) cascade
11:55
<Jenaf>
(unsolvability is NOT an error, it is an expected case)
11:58
<lpaste_>
ongy annotated “How to refactor” with “How to refactor (annotation)” at http://lpaste.net/353382#a353383
11:59
<ahri>
i'm writing a bomberman clone and i'm thinking about how to best model the exploding of bombs and resulting possible flame, which can in turn destroy powerups and walls. i was going to fmap over my [Bomb] but then i need to remove some of [Wall] and [PowerUp] in some cases, so: Bomb -> [Wall] -> [PowerUp] -> (Bomb, [Wall], [PowerUp], [Flame]) ..... is this sensible? i'm learning Haskell and feel like that
11:59
<ongy>
Jenaf: ^ Use the monad instance. It's nice
11:59
<ahri>
looks clunky, but have no idea how i might otherwise model it
12:00
<ahri>
hm, actually i have to return Maybe Bomb, as it may or may not explode
12:01
<Rodenbach>
I have a function, which works nicely to create one random Bar, with the signature: foo :: (PrimMonad m) => Config -> Gen (PrimState m) -> m Bar
12:01
<Rodenbach>
I create a rng via rng <- createSystemRandom
12:01
<Jenaf>
thats what you get when you forget your luggage at the airport: Maybe Bomb
12:01
<Rodenbach>
How can I now create a list [Bar] with 10 random Bars?
12:01
<SexHendrix>
Jenaf: lol
12:02
<Jenaf>
inb4 Just Nothing
12:02
<SexHendrix>
Bomb disposal teams were in JFK this morning after a suspicious package was discovered. The initial fear was Maybe Bomb but it was later confirmed to be Nothing
12:03
<ahri>
hehe, although in my case if it's Nothing, it just blew up so is no longer a Bomb ;)
12:05
<SexHendrix>
unsafeMaybe
12:05
<lambdabot>
Try -fglasgow-exts for GHC's newtype-deriving extension
12:07
<ahri>
so am i to assume that my suggested solution seems reasonably idiomatic for Haskellers? that's all i'm after really
12:10
<Athas>
ahri: I find something to be strange about your representation. What does [Wall] and what does [PowerUp] code?
12:10
<Athas>
Is a Wall a coordinate?
12:11
<ahri>
yeah, they both have a coordinate. powerup might be various types of powerup (more flame, more bombs, ... maybe other stuff if i get that far)
12:11
<Boomerang>
Rodenbach: Is that the random from sfmt? You could do something along the line of: traverse makeBar $ replicateM 10 createSystemRandom
12:12
<Athas>
ahri: can there be a powerup and a wall in the same location simultaneously?
12:13
<ahri>
Athas: no, when a wall is destroyed it has a random chance to leave a powerup in its place
12:14
<ahri>
it concerns me that my current model allows both to exist since they just have coordinates attached
12:14
<Athas>
ahri: in your representation, what happens if the [Wall] and [PowerUp] lists have conflicting entries?
12:14
<Athas>
Yeah, exactly.
12:14
<Athas>
That is a design smell.
12:15
<Athas>
Instead, I'd recommend the game board as a 2D-array of Things, where a Thing is then a bomb, a powerup, or a wall.
12:15
<Athas>
(Or some other encoding - the point is that it can only encode valid states.)
12:15
<Athas>
The only tricky thing is the player, since there can only be one of those, right?
12:16
<Boomerang>
Rodenbach: Actually you'll need to use bind with the code I gave you: traverse makeBar =<< replicateM 10 createSystemRandom
12:17
<ahri>
Athas: there are a few wrinkles like that: multiple players can be in one place. a player cannot move onto a square with a bomb on it, however when a player drops a bomb it is on the same square as whatever players currently reside on there
12:17
<Boomerang>
Where makeBar :: GenIO -> IO Bar
12:17
<Athas>
ahri: right, so maybe players should not be part of the game world as such, but stored separately.
12:17
<Athas>
But for everything else, the 2D array approach makes more sense.
12:18
<Athas>
It's not always about a design that eliminates *all* errors, just as many as practical.
12:18
<ahri>
Athas: ok, i guess flame should stay apart too, as it will cover a wall, and then when it's cleaned up i will decide whether or not to leave a powerup in its place
12:19
<Athas>
You could have an WallWithFlame cell state.
12:19
<ahri>
Athas: and a SpaceWithFlame?
12:20
<ahri>
i'd end up needing a PowerupWithFlame, too, actually, as they can be destroyed
12:21
<Athas>
ahri: maybe all cells should just have an onFire field.
12:22
<Athas>
But generally, don't be afraid of having many constructors. It just means you are being explicit about your states.
12:22
<merijn>
Athas: Well, too many might ruin your compile time :p
12:22
<Athas>
merijn: using Haskell might ruin your compile time.
12:23
<merijn>
Athas: Not as much as C++!
12:23
<Athas>
That battle's already lost!
12:23
<Athas>
Perhaps! Although 'make' seems to do a better job of parallelisation than GHC does.
12:24
<merijn>
Athas: My magic bash alias for superfast compilation: alias make='make -j32' :p
12:33
<ongy>
Athas: what? when I compile with ghc (well cabal) I have 100% usage on all cores
12:33
<ongy>
I dont' think that much more parallelisation is possible
12:33
<merijn>
ongy: How many cores do you have? :p
12:33
<ongy>
on this? 4+TH
12:33
<ongy>
but I have done it with 24 cores before
12:33
<merijn>
ongy: Right, that's pretty easy to saturate
12:34
<Athas>
ongy: how much faster is it?
12:34
<ongy>
Athas: then what? single core?
12:34
<ongy>
never tested, I'd asume roughly 6 to 7 times.
12:35
<ongy>
merijn: aren't you working on a cluster? shouldn't that be something like -j8192? :)
12:35
<Athas>
My experience is that it doesn't scale very well.
12:35
<merijn>
ongy: Jobs don't magically run on more than one machine
12:36
<merijn>
And I don't think make can handle multiple machines anyway
12:36
<ongy>
if you have single *huge* files, it doesn't. But for many small-ish files it's fine
12:36
<ongy>
well, that's what we can use distcc for. But I don't know hoe make -j# and distcc interact
12:37
<SexHendrix>
can lambdabot do IO
12:37
<cocreature>
SexHendrix: no
12:38
<ongy>
> putStrLn "It has a show instance"
12:38
<lambdabot>
<IO ()>
12:39
andrei_chifa joined
12:40
<Reisen>
Is there a recommended way of emulating anonymous union / sum types in Haskell?
12:40
<ongy>
hm Athas you are right. I was under the impression it parallelises better. But installing lens in a sandbox (with cabal) it's 1-3 cores most of the time. does 'cabal build' do something different?
12:41
<Athas>
ongy: yes, building multiple *packages* works quite well.
12:42
<Athas>
I think it just launches several GHC processes.
12:42
<Athas>
It's compiling a single multi-module package that doesn't scale much.
12:42
<ongy>
Athas: cabal build in the lens package multithreads properly
12:43
<lambdabot>
run <expr>. You have Haskell, 3 seconds and no IO. Go nuts!
12:43
<ongy>
though it doesn't saturate all cores all of time either
12:44
<Athas>
I think GHC has some sequential bottlenecks.
12:44
<Athas>
Or shared critical regions.
12:44
<Athas>
Maybe the FastString stuff.
12:44
<ongy>
which is probably more of a problem with the dependencie graph of the modules in it. For my own, which has very few inter-dependencies it's all cores all the time
12:45
psychicist__ joined
12:46
<Athas>
It doesn't matter how much you can utilise your cores. That's just heat. Only the wall-clock time matters.
12:46
<Athas>
You can get great utilisation by spinning on a lock.
12:46
<ongy>
it's an indicator, provided things don't spin on locks
12:47
<Athas>
Or the cores trash each others caches.
12:50
cobreadmonster joined
12:53
<Jenaf>
Yay my Code works as intended so far ^.^
12:58
<michalrus>
Hey, is there traverseM in Haskell? Like in https://git.io/vywEQ i.e. traverse+join.
12:59
<michalrus>
Or rather https://git.io/vywuJ
13:01
<teto>
how to disambuguate instances: I have "The type variable ‘a0’ is ambiguous" ; full error here http://paste.ubuntu.com/24151500/
13:02
<reactormonk>
!hoogle (Monad f, Applicative g) => f a -> (a -> g f b) -> g f b
13:03
<reactormonk>
michalrus, http://hayoo.fh-wedel.de/?query=%28Monad+f%2C+Applicative+g%29+%3D%3E+f+a+-%3E+%28a+-%3E+g+f+b%29+-%3E+g+f+b
13:04
<michalrus>
So it’s useful in Scala but not in Haskell? (:
13:04
<reactormonk>
Implement it, can't be too hard.
13:06
<lambdabot>
(Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
13:06
<lally>
Hi, I've got a lens question
13:07
<ongy>
:t join . traverse
13:07
<lambdabot>
Traversable t => (a -> t a -> b) -> t a -> t b
13:09
<lally>
I've got a list of a sum type, and want to get the last one that has a value for a given lens
13:09
<lally>
Is there something smaller than last $ catMaybes $ map (preview myLens) list ?
13:09
<Gurkenglas_>
lastOf (traverse . myLens)
13:10
<lally>
Nice! Thanks
13:11
<Gurkenglas_>
Though it's more of a traversal than a lens if it only matches sometimes
13:11
andrei_chifa joined
13:13
<Gurkenglas>
Hmm maybe lambdabot should get a module that defines undefinedLens :: Lens s t a b, undefinedTraversal :: Traversal s t a b, undefinedLens' :: Lens' s a, and so on, just so :t demonstrations don't explode into high-end typeclassery
13:14
<ski>
@let undefinedLens :: Lens s t a b; undefinedLens = undefined; undefinedTraversal :: Traversal s t a b, undefinedLens' :: Lens' s a
13:14
<lambdabot>
Parse failed: Parse error: ,
13:15
<ski>
@let undefinedLens :: Lens s t a b; undefinedLens = undefined; undefinedTraversal :: Traversal s t a b; undefinedTraversal = undefined; undefinedLens' :: Lens' s a; undefinedLens' = undefined
13:15
<lambdabot>
.L.hs:167:1: error:
13:15
<lambdabot>
Duplicate type signatures for ‘undefinedLens’
13:15
<lambdabot>
at .L.hs:158:1-13
13:16
<Gurkenglas>
Ya but that's gonna disappear after every @undefine. Though I guess I can query those to lambdabot when I need them...
13:16
<Cale>
:t undefinedLens
13:16
<lambdabot>
error: Variable not in scope: undefinedLens
13:16
<ongy>
:t undefinedLens
13:16
<lambdabot>
error: Variable not in scope: undefinedLens
13:16
<Cale>
What would the purpose of those be?
13:16
<Gurkenglas>
case in point, just did @undefine right after he said that in query to test whether they're actually in L.hs
13:18
<Gurkenglas>
:t lastOf (traverse . undefinedTraversal) -- So you can say this instead of:
13:18
<lambdabot>
Traversable t => t s -> Maybe b
13:18
<Gurkenglas>
:t lastOf (traverse . ?f)
13:18
<lambdabot>
(?f::(a -> Const (Rightmost a) a) -> a1 -> Const (Rightmost a) a1, Traversable t) => t a1 -> Maybe a
13:19
<Cale>
Then again, I'm not sure "Traversable t => t s -> Maybe b" is much more comprehensible
13:19
<Cale>
(though I suppose it's perhaps fine if you know the type variables used in undefinedTraversal)
13:20
<Gurkenglas>
Yeah, not sure why I expected something to produce a reference to the connection between s and a there
13:22
<Gurkenglas>
What's a good way to say this, for example something that produces (?f::Traversal s t a b, Traversable t1) => t1 s -> Maybe b
13:24
<drdo>
I want to print data similarly to the derived Show instances but with full indentation (in a sexp-like fashion). Is there something for this?
13:25
<Cale>
drdo: perhaps http://hackage.haskell.org/package/groom
13:26
<Cale>
http://hackage.haskell.org/package/groom-0.1.2/docs/src/Text-Groom.html#groom -- as you can see here, it's a really simple application of haskell-src-exts
13:26
<Cale>
So you could also just use haskell-src-exts directly
13:26
<lally>
Is there a better way to learn lenses than th FPComplete tutorial + a lot of mucking around in ghci?
13:27
<drdo>
Cale: I guess I could try it, but from the very first example on the page, it doesn't look like it's what I want
13:28
<Cale>
lally: Perhaps start with some lens library which isn't 'lens'. The main lens library is great, but it's got a lot of stuff that is simply irrelevant when you're trying to learn the most important bits.
13:28
<drdo>
Maybe there's a prettyPrint with this option
13:28
<drdo>
I guess I'll check haskell-src-exts
13:29
<lally>
n.m. just saw the FAQ off the lens package. I'll hunt through there first.
13:30
<bennofs>
drdo: try pretty-show
13:30
<bennofs>
@hackage pretty-show
13:30
<lambdabot>
http://hackage.haskell.org/package/pretty-show
13:31
<Cale>
hmm, I was thinking of lens-family, but it seems to have become oddly abstracted as well now too.
13:33
<Cale>
lally: I guess the real answer is "be around back when lenses were being invented for the first time and everything was much simpler" ;)
13:34
<bennofs>
Cale: lens-family-core?
13:34
<Cale>
Well, even that has the weird FoldLike shenanigans in it
13:35
<Cale>
Is there anything which *just* does van Laarhoven lenses, without abstracting over various sorts of getters and setters and traversals and whatnot?
13:37
<bennofs>
Cale: microlens doesn't look too bad
13:38
<Cale>
It still does the ASetter / Getting stuff, but yeah, it's closer to what I'd want in order to teach someone about lenses the first time.
13:39
<Cale>
I'd also kill off the infix operator shenanigans, but that's just personal preference ;)
13:40
<drdo>
Ah, screw it, I'll just roll my own printer
13:40
<drdo>
These things want to do fancy choices and all I want is simple consistent indentation
13:48
<cris_>
hi , i write a small module to supplement postgresql-simple , it is to let larger size tuple to use with postgresql-simple, https://github.com/szehk/Haskell-Carbonara-Library/blob/master/src/Database/Carbonara/PostgreSQL.hs
13:49
<cris_>
i myself need to upload to postgres database with tuple size large than 40 , so i need to write it myself , do you think this will be useful to other haskeller as well?
13:50
<hexagoxel>
drdo: so you want something like the last example in the readme of http://hackage.haskell.org/package/GenericPretty
13:50
<teto>
anyone could help me disambiguate " The type variable ‘a0’ is ambiguous" in https://github.com/teto/vim-config/blob/master/test.hs (just runhaskell test.hs), it's my first haskell program and I don't think setting the returned value might disambugate thing (please ^^)
13:50
<merijn>
teto: What's the full error?
13:51
<teto>
merijn: full error here http://paste.ubuntu.com/24151500/
13:52
<teto>
(btw I tried cabal update to get cassava 0.4.5, but it stays with 0.4.4)
13:52
<merijn>
teto: You never use part of the result, so GHC can't infer what type you're wanting
13:53
<teto>
merijn: I see thanks got it
14:12
mizu_no_oto_work joined
14:17
<matchwood>
Hi all, I've tried asking this haskell-stack but nobody seems around so thought I'd give it a go here...
14:17
<matchwood>
The question is basically about configuring stack for ghcjs
14:17
<matchwood>
http://stackoverflow.com/questions/42720347/how-to-configure-stack-for-most-recent-ghcjs-lts-build
14:18
<matchwood>
Any thoughts greatly appreciated!
14:22
<shiona>
Does anyone know of a haskell-diagrams (or similar) web repl? I'm sure I've used something like that in the past, but now I cannot find such a thing.
14:30
<Jenaf>
anything wrong with those two lines?
14:30
<Jenaf>
http://lpaste.net/353390
14:30
<Jenaf>
(except my fetish for parans)
14:39
<Cale>
Jenaf: Well, I would add an import Data.Sequence (Seq) to the top of the file so as to avoid needing to write Seq.Seq
14:39
<Cale>
also you *really* don't need parens around single tokens
14:39
<Jenaf>
um, I did import Data.Sequence as Seq
14:39
<Cale>
(Bool) is always going to be the same thing as writing Bool
14:39
<Jenaf>
I was beeing scared of namespace collisions
14:39
<Cale>
You should do:
14:39
<Cale>
import qualified Data.Sequence as Seq
14:39
<Cale>
import Data.Sequence (Seq)
14:40
<Jenaf>
also I found another error
14:40
<Cale>
The import qualified will make sure you need to use an explicit "Seq." qualifier to refer to things from that module, and then the second import removes that restriction for the type itself.
14:41
<Cale>
Another thing you can do is to remove the lambda and pull that argument over to the other side of the = sign
14:41
<Cale>
filterHelper numList bools = toList ...
14:43
<Jenaf>
but I think I have my main reduction step for sudoku solving done. ^.^
14:43
<Jenaf>
140 lines of haskell feel a bit much thou
14:43
<Cale>
I'm also not certain that it's actually better to be using Seq.zip rather than doing the toLists sooner
14:43
<Cale>
but that's pretty minor
14:44
<Jenaf>
yeah thats really quite minor ^.
14:53
<kuribas>
You may get better fusion with lists.
14:53
<kuribas>
Does that typecheck?
14:55
<kuribas>
wouldn't it return [(Int, Bool)]?
15:02
<kuribas>
Jenaf: confirmed by ghci
15:03
<Denommus>
do you guys use any package for gherkin specifications?
15:04
<Denommus>
it's essential to us to make specifications in a human-readable language
15:04
<Jenaf>
kuribase: yeah that was the error i was talking about earlier
15:08
<unclechu>
hey guys, i'm trying to get coverage info from Stack, i'm trying to build my app by command `stack build --coverage` but getting this error at the end: `No tix files found in /--myapppath--/.stack-work/install/x86_64-linux/lts-6.30/7.10.3/hpc/, so not generating a unified coverage report.`
15:08
<unclechu>
what should i do?
15:32
<nitrix>
unclechu: I think you're supposed to compile with -fhpc to get .tix files.
15:33
<unclechu>
nitrix: how should i do it?
15:33
<nitrix>
I think you compile your executable with -fhpc, then run the executable, the runtime should generate a .tix file, which you can then generate reports from.
15:34
hackebeilchen joined
15:35
<unclechu>
nitrix: how i can compile my executable with `-fhpc` flag?
15:35
<unclechu>
`stack build --help` doesn't show any available fhpc flag
15:36
<nitrix>
The ghc-options section of your cabal file is possibly the easiest way.
15:37
<nitrix>
stack build --ghc-options=-fhpc ?
15:38
<nitrix>
Does stack lets you do that?
15:40
hackebeilchen joined
15:43
<unclechu>
nitrix: thanks, now it's working, but coverage value is defenetely not right
15:43
<unclechu>
or i misunderstand something
15:44
<unclechu>
here it is: http://pastebin.com/H49Lyyg2 but my tests cover very small percent of the `library`
15:46
<unclechu>
i'm looking at report right now and it shows only modules i imported in tests
15:47
<unclechu>
maybe it's correct, but i prefer to show there everything from `exposed-modules`
15:52
<Jinixt>
a design question: a Game has Players which have Cards; a Card can have wildly different effects, so right now it has a function with the type "State Game" to perform these effects. it feels like i'm giving too much 'power' to the cards since they can do anything they want with the Game. is there a better idiomatic way?
15:53
<Jinixt>
i've toyed with the idea of a simple DSL for describing the effects, but i'm looking for other alternatives as well
15:54
<lyxia>
I was about to suggest enumerating the effects in an ADT but that's basically what you just said.
15:55
<merijn>
Jinixt: Difficult trade-off
15:58
<Jinixt>
it feels like it would be nice to be able to enumerate what sort of "permissions" a Card is asking for, if you will
15:58
<Jinixt>
"why is this card asking for delete permissions?"
15:58
<teto>
is it possible to embed an if/else (or case) in a lambda ?
15:59
<cocreature>
teto: sure, just use it like anywhere else
16:00
<merijn>
Jinixt: The "State Game" approach gives you maximum flexibility, but it's harder to restrict things
16:00
<Boomerang>
teto: for example (\x -> case x of Just a -> True; Nothing -> False), you can even use the LambdaCase extension to make it shorter to write
16:00
<merijn>
Jinixt: Enumerating it eliminates that, but becomes more verbose/hassle-like if you wanna add new behaviour
16:01
<Jinixt>
i can imagine there's only a relatively limited set of things you'd want to do anyways
16:02
<Jinixt>
the only thing missing is that if you have branching you can't see -all- possible effects easily, but perhaps that's a pipe dream
16:02
<Jinixt>
or would require manually stating that first, which is also a hassle
16:06
<padre_angolano>
I want to start learning Yesod. The homepage http://
www.yesodweb.com/ makes reference to the first edition of the O'Reilly book (2012), whereas the 2-nd edition (2015) is already available. Is there a specific reason why the yesod site recommends the outdated edition?
16:06
uglyfigurine joined
16:07
<padre_angolano>
Or maybe the yesod website itself was not updated since 2012?..
16:07
<Clint>
padre_angolano: probably nobody noticed the discrepancy
16:08
<Reisen>
So, if I had Either (Either A B) C, and I want to serialize the value contained with aeson (Just the value, not the Right/Left's of the Either), I can write a simple pattern match and do that easily
16:08
<padre_angolano>
Clint: hmm...
16:08
<Reisen>
But if I want to do the reverse, and I have an aeson serialized A, B, or C, and I want to write something that looks like: decode :: Text -> Either (A B) C
16:09
<Reisen>
I feel like I'm stumped on how I'd know how many Left/Right's would be needed to construct the right result, or how to traverse the type
16:09
<Reisen>
Can someone point me in the right direction on what I should read about, or if this is impossible?
16:10
<smaug_>
Is Haskell impractical to learn?
16:10
<ongy>
Reisen: unless you have some information in there about whether it's an A, B or C you can't (how would you decide what it is?)
16:11
ChristopherBurg joined
16:11
<ongy>
smaug_: it's different, so when you are coming from oop/imperative languages it may be a bit harder at first
16:11
<Taneb>
smaug_, there's not as many resources to learn from as as a more popular language like Python, say
16:11
<Reisen>
ongy, I don't mind tagging the resulting encoded value with the type that it is
16:11
<ongy>
if you are coming from maths or using it as first language, it may even be easier
16:11
<Taneb>
smaug_, but I think once you get the hang of it it ends up quite easy
16:12
<smaug_>
Is Haskell best for AI?
16:12
<Boomerang>
Reisen: In that case I believe Aeson already provides you with instances for FromJSON and ToJSON fro Either a b
16:12
<merijn>
padre_angolano: I would suspect they forgot to update the site
16:12
<ongy>
Reisen: then you know what it is by from the type. if it's A it's (Left (Left val)) and so forth
16:12
Lord_of_Life joined
16:12
<Taneb>
smaug_, I don't know of much people writing AI code in Haskell
16:12
<Boomerang>
And it "tags" the data with "Left" and "Right"
16:12
<Reisen>
Boomerang that's the thing though, I don't want to encode the Either part, I.E, I want to store something that looks like
16:12
<Reisen>
Just "{"type": "C", "C { ... }"}
16:13
<Reisen>
And then at runtime, figure out the right amount of Left's/Right's needed
16:13
<Reisen>
When pulling it out
16:13
<Reisen>
Without having to hand write the instances, if that makes sense
16:13
<Reisen>
Essentially I'm trying to write a ghetto emulation of anonymous sum types
16:13
emmanuel_erc joined
16:14
<smaug_>
Why should I learn Haskell? Give me some good reasons.
16:14
<Boomerang>
Reisen: You would probably be better of having a sum type: data MyData = MyA A | MyB B | MyC C, or do you need it to be Either?
16:14
<Reisen>
Boomerang, I need it to be either because, there are some 15 types that I have stored, and I want to be able to do something that looks roughly akin to:
16:14
<Reisen>
type (:|) a b = Either a b
16:14
<Reisen>
And right functions that can work on any pairing, I.E
16:15
<Reisen>
x :: (A :| B :| Z :| G) -> ()
16:15
<Taneb>
smaug_, because it is a productive language that can change how you think about and program in other languages for the better
16:15
<Reisen>
y :: (A |: R |: N) -> ()
16:15
<Jinixt>
sounds like a list, Reisen
16:15
<ongy>
smaug_: because you want to broaden your horizon. Also that question reaks of troll
16:15
<Reisen>
It is like a list, except that I don't want a product I want a sum
16:15
<Reisen>
I think, THINK this is the UnboxedSum extension that might get merged at some point
16:16
<dunx>
smaug_: https://
www.cs.utexas.edu/users/EWD/OtherDocs/To%20the%20Budget%20Council%20concerning%20Haskell.pdf
16:16
<Reisen>
Where I'd be able to write, x :: (A | B | C) -> () and use case x of ( A ||); (| B |) and so on
16:16
<Reisen>
but It's not implemented yet
16:16
<smaug_>
ongy, I don't an answer from people like you. Go away.
16:16
<ski>
Reisen : unboxed or anonymous/light-weight ?
16:16
<ongy>
you accidently all the :)
16:17
<Reisen>
ski, I'm not really looking for unboxed it just happens the (||X) syntax is part of the UnboxedSums extension from what I can tell
16:17
<Reisen>
anonymous sum types is what I'm after
16:17
<Reisen>
but they don't exist so I'm trying to get as close as possible
16:17
<ski>
(OCaml has them, e.g.)
16:19
<ski>
i'd perhaps call them "positional sum types", since the alternatives are determined by position (as for tuples), rather than by name (as for records, and for "ordinary" sum types with data constructors)
16:19
<Reisen>
That is exactly what I'm after more or less
16:20
<Reisen>
I'm thinking that maybe I could traverse an Either type with some sort of type level function in order to determine that position
16:20
<ski>
(OCaml's "polymorphic variants" have alternatives determined by name. but you dont' have to declare the types beforehand, you can just use them, as with e.g. tuples)
16:21
<smaug_>
Fucktional programming has ugly syntax
16:21
<dunx>
go away then
16:21
<ski>
it has different syntax
16:21
<dunx>
i like the syntax
16:21
<dunx>
mathematival
16:21
<ongy>
Reisen: I think this may be a job for template-haskell.
16:21
<* ski>
doesn't think there's any reason to be unfriendly
16:22
<Reisen>
ongy, I think you may be right
16:22
<ski>
(heh. that applies to both of you :)
16:22
ragepandemic joined
16:22
<ongy>
but then you need one instance for each version (arity?) of the sum you use. So probably not that practical either
16:22
<Taneb>
smaug_, there are many different functional programming languages, and many different syntaxes!
16:23
<Reisen>
I'm sure there's a way to write a type level traversal, something like monad-classes liftN
16:23
<Reisen>
I'll give it some thought
16:23
<Tuplanolla>
Syntices?
16:23
<dunx>
ski: i didn't mean to be unfriendly :(
16:23
<ski>
if you like brackets, you might try Scheme
16:23
<Taneb>
Haskell looks very different to Lisp looks very different to Erlang looks very different to Scala
16:23
serendependy joined
16:23
<Reisen>
I was kind of hoping maybe the concept had been done before and I'd get a "you want X-package Reisen" style answer
16:23
<Reisen>
but It's cool, it'll be fun to play with this idea
16:23
<ski>
dunx : regardless, "go away" could easily be construed as such
16:23
<cocreature>
is there any way to get the exact logbase2 of a Word64 using base < 4.8 (and no other packages)?
16:24
<MarcelineVQ>
Reisen: if you were wanting to try unboxed sums you could build ghc head which has them
16:24
<Reisen>
Yeah, I just don't want my project relying on GHC head
16:24
<Reisen>
I want to stay on a stackage LTS release
16:24
<ongy>
cocreature: exact logbase2? How would you store that?
16:25
<MarcelineVQ>
You can use head with stack if that's your only sticking point :>
16:25
<cocreature>
ongy: I don’t understand that question :)
16:26
<MarcelineVQ>
anyway it was just to try it, if you're waiting for something more official 8.2 will have them
16:26
<Tuplanolla>
Rounded up or down, cocreature?
16:26
<cocreature>
ongy: 4.8 allows me to use countLeadingZeroes but that doesn’t exist
16:26
<cocreature>
Tuplanolla: rounding down
16:26
<ongy>
cocreature: is log_2 guaranteed to be representagle in finite memory?
16:26
<cocreature>
ah sorry yeah exact was a bad term
16:26
<cocreature>
I wanted to say integer and for some reason I said exact
16:27
<Taneb>
Tuplanolla, syntaxes or syntaxies I think
16:27
<ski>
smaug_ : most languages other than functional programming ones are weak on expressing sum types and pattern-matching. for that reason alone, i'd suggest learning a functional programming language (such as Haskell,Erlang,OCaml,SML,F#, e.g.)
16:27
<cocreature>
by exact I was referring to the fact that I’d like to avoid floating point errors as caused by log x / log 2
16:28
<ski>
smaug_ : note that one of the core concepts in object-orientation is "record/struct types", aka "product types". product types are "dual" (complementary) to sum types. in practice, you should know about both of them
16:28
<ongy>
cocreature: how would countLeadingZeroes help you? do you know it's just a single bit?
16:29
<cocreature>
ongy: logBase2 x = finiteBitSize x - 1 - countLeadingZeros x
16:29
<ongy>
oh because we are rounding, right
16:30
<ongy>
copypaste the code of countLeadingZeroes?
16:30
<cocreature>
it’s a primitive :)
16:30
<ski>
smaug_ : another thing that functional programming is heavy on is treating functions as "just another kind of value", passing functions as arguments, computing them at run-time, returning them, storing them in data structures. passing functions as input and output yields higher-order functions, which are good to reduce more complicated patterns of boiler-plate code than ordinary (first-order) functions can reduce
16:30
<cocreature>
but yeah I might just write a shitty implementation myself
16:31
<ongy>
binary search for it :)
16:31
<cocreature>
I was hoping something like that might already exist somewhere in base and I’m just unable to find it
16:31
<cocreature>
ongy: I feel kind of bad for doing a binary search when my cpu can do this in a single instruction :)
16:31
<smaug_>
ski, most languages are multiparadigm
16:32
<ski>
smaug_ : most functional languages discourage "side-effects", if not completely disallowing them. you might have an easier time getting started with one which allows them, but then you might not as easily learn alternative modes of expression. it's a trade-off
16:32
<Taneb>
smaug_, multiparadigm rarely means "good at all of them"
16:32
<ongy>
cocreature: inline-c inline-assemble it? :P
16:32
<cocreature>
ongy: heh :)
16:32
<ski>
smaug_ : most languages have assignment and mutation all over the place (in standard libraries, e.g.) .. which is hardly conducive to doing functional programming
16:32
<ongy>
also the single instruction may not be as good as it sounds. Way better than doing it yourself though
16:33
<smaug_>
ski, what is the best language paradigm?
16:33
<Cale>
smaug_: Another reason to learn Haskell is to find out what it's like to actually have a useful type system that helps you make large refactors to your codebase far more easily, and catches the vast majority of stupid bugs for you.
16:33
<Taneb>
smaug_, that is not a question with an answer
16:34
<ski>
smaug_ : i'd also like to mention "logic programming" (e.g. Prolog), which is based on expressing computation using *relations*, rather than functions. relatively often, it happens that one can run these relations both "forwards and backwards", getting "two (or more) for one", with a single implementation
16:34
<viuo>
Hi everybody! Im trying to write a sort of expression evaluator. I have State Monad with an expression and an "environment" (the map + some other stuff). Unfortunately the algorithm I am implementing, treats the map as a global so if you set a var inside an expression it should be accessible from the outer ones too. The question is - do you know of any way I could propagate the state up the ladder so I can
16:34
<viuo>
read a variable from the surrounding expression too ?
16:34
<ski>
smaug_ : imho, it's best to learn about all the major paradigms, and try to learn which one is the best tool for any given job
16:34
<ski>
(which is why i was mentioning logic programming as well)
16:36
<ski>
smaug_ : the point is to broaden your horizons, which will improve your programming skills also in Java or Python or whatever ..
16:36
<shapr>
I see a lot of illogic programming at my day job.
16:36
<ongy>
haha thank you ski
16:36
<* ski>
idly wonders which language(s) would be the best exponent(s) for the paradigm of illogical programming ..
16:36
<shapr>
smaug_: want to see some cool code I wrote to get subway times for the nearby stops in Atlanta?
16:37
<Cale>
On the other hand, once you know Haskell well enough, programming in Java or Python will be an absolutely terrible experience and you will hate it.
16:37
<djfo>
viuo: you may want to try using the State monad
16:37
<smaug_>
shapr, sure.
16:37
<djfo>
viuo: do you have an example expression?
16:37
<Cale>
(but you will be better at it than before)
16:37
<ongy>
ski: for going full circle. I started with your last statement
16:37
<shapr>
smaug_: right now the output in my tmux status bar: ["M:Arriving,4","N:3,10"] and the source is: https://github.com/shapr/tmuxmarta/blob/master/src/Lib.hs
16:38
<shapr>
smaug_: have you written Python before? Are you familiar with list comprehensions?
16:38
<ongy>
shapr: you really love that piece of code
16:38
<smaug_>
shapr, not much
16:38
<viuo>
djfo: I am using a state monad but i cannot update the variable on the upper expression
16:39
<* ski>
idly wonders whether someone should ask smaug_ about what language(s) they're comfortable with, so far
16:39
<shapr>
ongy: it's a single file self contained example that does something useful, do you have others you'd suggest?
16:39
<Cale>
shapr: wow, fancy list comprehension :)
16:39
<shapr>
Cale: yeah! TransformListComp code by napping :-)
16:39
<viuo>
djfo: let me think how to visualize it
16:39
<smaug_>
ski, I am from low-level world ;)
16:39
<ongy>
I didn't say that it's bad, or that I have something better
16:39
<shapr>
smaug_: oh, you want embedded Haskell then?
16:40
<ongy>
smaug_: so ada/assembly, or closer to C?
16:40
<shapr>
ongy: I'd much prefer to have a long list of "working program in one file" examples.
16:41
<Denommus>
so, it seems there isn't a usable gherkin parser in Haskell, right?
16:41
<ski>
shapr : `let station = event ^. station' ?
16:41
<Denommus>
I wonder how difficult it would be to create one with megaparsec
16:41
<shapr>
Denommus: https://github.com/sakari/haskell-gherkin ?
16:41
<ski>
smaug_ : that's nice :)
16:41
<shapr>
smaug_: oh yeah, fun stuff. I got the risc-v arduino recently, it's really cool
16:42
<Cale>
smaug_: Back around 2004 or so, I had the experience of writing a pipeline scheduler for PPC/Altivec in Haskell for a research project. We used it to optimise some vectorised code for computing sine/cosine pairs so that it operated at about 2.6 clocks/float (by extremely unfair comparison, GNU libm's cosine takes a couple hundred clock cycles)
16:42
<viuo>
djfo: http://pastebin.com/DmcJPgMe here's my code
16:42
<Cale>
Haskell can make a really good metalanguage for low-level work
16:42
<shapr>
ski: yeah, that lens grabs the station field from this event
16:43
<ski>
i meant, why not use `let' there ?
16:43
<viuo>
djfo: it's a little messy, I just started with haskell, excuse if it hurts the eyes ;) could use a review
16:43
<Cale>
Basically, my thing did a simulation of the units on a particular PPC/Altivec CPU and rearranged the instructions such that as many different functional units in the processor could be operating simultaneously.
16:43
<Taneb>
ski, well, you couldn't use the name "station"
16:44
<Cale>
(Modern processors are really non-obvious to optimise assembly code for by hand)
16:44
<viuo>
djfo: in general, when evaluating MuExpr, the i want to be able to set a variable and then re-use it in the next iteration of fixpoint
16:44
<shapr>
smaug_: if you decide you want to learn Haskell, I'm a big fan of haskellbook.com
16:45
<shapr>
smaug_: although if you want free learning materials, byorgey's course is really nice
16:45
<ski>
viuo : instead of `e <- get' and then later `symbols e', you could use `old <- gets symbols' and then later `old' ..
16:45
<shapr>
@where cis194
16:46
<ski>
viuo : oh, yeah, `getSymbols = gets symbols'
16:47
<viuo>
ski: yeah it's a bit messy
16:47
<ski>
viuo : i'd suggest looking into `modify', possibly defining `modifySymbols' and `modifyBinding', using it
16:48
<smaug_>
shapr, yes the book sounds good.
16:48
<ski>
viuo : in `assign', the last `return ()' is redundant, since the type of `setSymbols new' is already `Evaluator ()'. the return value of that will just be propagated
16:48
<viuo>
ski: oh right, will fix
16:49
<cocreature>
ongy: ah the class providing countLeadingZeros has a default implementation so I can be lazy after all and just copy it :)
16:50
<ongy>
cocreature: are you doing this for compat reasons, or because you need 4.8?
16:50
<cocreature>
ongy: I’m doing this because hackerrank doesn’t have base 4.8 :)
16:50
<viuo>
ski: I am not sure I understand what modify does
16:50
<ongy>
oh hakerrank
16:51
<ongy>
that probably doesn't do FFI
16:51
<ski>
viuo : `modify' takes a function, call it `f', gets the state, applies the function to it, and puts the result back
16:52
<Profpatsch>
Does anyone know how I pattern match on structures using Data.Fix?
16:52
<Profpatsch>
e.g. I have an NExpr from https://hackage.haskell.org/package/hnix-0.3.4/docs/Nix-Expr.html#t:NExpr
16:52
JeanCarloMachado joined
16:53
<Profpatsch>
It’s parsed in from a string.
16:53
<Profpatsch>
Now I want to transform it in a certain way.
16:53
<ski>
viuo : `modifySymbols f = modify (\(Environment ks old b el) -> Environment ks (f sym) b el)', e.g., could be used in `assign'
16:53
<Taneb>
Profpatsch, you can match on Fix (NConstant c) for example
16:53
<viuo>
ski: oh right I get it now
16:54
<Profpatsch>
Taneb: Interestingly, this is the Show instance of Fix: https://hackage.haskell.org/package/data-fix-0.0.3/docs/src/Data-Fix.html#line-68
16:54
<Profpatsch>
So the printed value skips all the Fixes
16:54
<Profpatsch>
I wonder if there is no nice pattern matching for that?
16:54
<ski>
Profpatsch : bad instance ..
16:55
<ski>
(doesn't even define `showsPrec')
16:55
<Taneb>
Profpatsch, the Show instance doesn't affect the pattern matching one iota
16:55
<viuo>
ski: I am concerned mostly about the evaluate. So for instance if I have a AndExpr where I have expressions A and B , I want all the assigns from A and B get propagated so in AndExpr I can read those assigns
16:55
<ertes>
in what way is GHC's Any type different from, say, Void?
16:56
<Profpatsch>
Taneb: Yes, of course.
16:56
<ski>
viuo : should work with a state monad, iiuc
16:56
<viuo>
ski: damn can't express myself properly... basically I want the SymTab in the State to be shared between all the expression
16:56
<ski>
what does "shared between all the expression" mean ?
16:57
<viuo>
so far what I get is I can read assigns going downwards but I want it to work both ways
16:57
<Profpatsch>
Taneb: I should be able to use one of cata ana hylo for that, but I’m not entirely sure, how.
16:57
<nitrix>
viuo: You'll have access to the state as long as your computations happen within the stateful monadic context.
16:57
<viuo>
ski: in the original algorithm - SymTab is a global variable
16:57
<Taneb>
Profpatsch, it can be hard to get an intuition for those, I've found
16:57
<Taneb>
I'd just use explicit recursion
16:58
<ertes>
ah, nevermind
16:58
<ski>
viuo : yes, go on ..
16:58
<viuo>
ski: that is when you evaluate an expression where a child expression sets a variable to 1. This variable should return 1 in the parent expression too
16:58
<Profpatsch>
Taneb: Probably.
16:58
<Profpatsch>
I’m sure there is a nice way to do structure conversion.
16:58
<ski>
viuo : yes, that should happen automatically, if you set up the evaluator right, using a state monad
16:59
<Profpatsch>
Having all these Fixes everywhere is kind of suboptimal.
16:59
<ski>
(which, at a quick glance, it looks like you're doing. perhaps i'm missing some detail ?)
16:59
<Profpatsch>
Maybe with ViewPatterns
17:00
<ski>
Profpatsch : `foo (Fix x) = case x of NConstant atom -> ...; ...' ?
17:00
<ski>
(or with a helper function, if you prefer)
17:00
<ski>
(`cata' or whatever could also be useful, yes)
17:01
<eacameron>
What's the best way to provide lenses for my datatypes to downstream users (it's a library) without bringing in all of lens dependency?
17:01
<viuo>
ski: unfortunately what I get is the state only get passed down
17:01
<Profpatsch>
If I want to match deeper into the structure, it will be (Fix (Constr (Fix Constr2 (Fix …
17:02
<Gurkenglas>
eacameron, https://github.com/ekmett/lens/wiki/How-can-I-write-lenses-without-depending-on-lens%3F
17:02
JeanCarloMachado joined
17:02
<viuo>
what I would like to do is something in a sense of. I do new <- eval and later on i set the current state to what was calculated in "new"
17:03
<eacameron>
Gurkenglas: Hah, wow. Just for me? ;)
17:04
<viuo>
ski: I googled a module called Tardis which looks like something that would be relevant here
17:04
<Profpatsch>
convertToNewstyle (Fix (NWith _ (Fix (NWith _ a)))) = a
17:04
<ski>
Profpatsch, yes
17:04
<Profpatsch>
Has to be nice somehow. :(
17:04
<ski>
pattern synonyms could be helpful
17:05
<Profpatsch>
Complaining on a very high level. :P
17:09
<ski>
viuo : `MuExpr' and `NuExpr' always has `FixedPointExpr fp' in first component ?
17:09
<viuo>
ski: yes, correct
17:09
<viuo>
ski: FixedPoint is a variable that I set in SymTab
17:11
<ski>
why not just have `MuExpr fp f' instead of `MuExpr (FixedPointExpr fp) f', and similarly for `NuExpr' ?
17:11
<Profpatsch>
johnw: You wrote hnix, have you find
17:11
<* ski>
figures this is some kind of modal logic thing ..
17:11
<Profpatsch>
*found a nice way to match on Fix Structures?
17:11
<Profpatsch>
convertToNewstyle (Fix (NWith _ (Fix (NWith _ a)))) = a
17:11
<Profpatsch>
That’s a bit verbose.
17:12
<viuo>
ski: yeah Im trying to implement EmersonLei Model Checking
17:12
<Profpatsch>
As in many Fix Constructors.
17:12
<* ski>
's never heard of "Emerson-Lei" befoer
17:12
<viuo>
FixedExpr comes from the parser
17:12
<viuo>
you can have a freestanding FixedExpr too
17:12
<ski>
can you fix the AST ?
17:12
<ski>
yes, but that seems to me to be a different thing
17:13
<ski>
aiui, `MuExpr' and `NuExpr' represents binders in the object language
17:13
<ski>
as such, it would make sense to not (typewise) allow any expression in the first component, but only an identifier
17:13
JuanDaugherty joined
17:14
<viuo>
that's correct
17:14
<viuo>
should never come to this though
17:15
<viuo>
it does not change much since im ignoring it as an expression anyway
17:16
<ski>
do you have a simple example of "what I get is the state only get passed down" ?
17:16
<viuo>
okay let me write you an expression
17:18
<viuo>
MuExpr (FixedPoint 'A') (MuExpr (FixedPointExpr 'B') (DiamondExpr 'action' (FixedPointExpr 'B')))
17:19
<ski>
and are we talking about `eval' here ?
17:19
<viuo>
so eval of MuExpr will evaluate it as long as it doesn't return the same value twice
17:20
<viuo>
no consider the inner MuExpr first
17:20
<viuo>
we set the B to be the set of all states at first
17:20
<viuo>
and then we evaluate the DiamondExpr as long as it returns different values
17:21
<viuo>
when we get two same values we set B to the result
17:21
<viuo>
now consider the outer MuExpr
17:21
<viuo>
we start here before evaluating the inner one
17:22
<ski>
using `newEnvironment' or `newEmersonLeiEnvironment' as initial state ?
17:22
<ski>
(i'd s/new/init/ there, fwiw)
17:22
<viuo>
newEmersonLeiEnvironment
17:22
<viuo>
init is for assigning the initial values
17:23
<viuo>
now when evaluating the outer MuExpr (For A) we will have to repeat the same operation eval MuExpr for the inner one (B)
17:23
<ski>
(i meant renaming them to `initialEnvironment' and `initialEmersonLeiEnvironment', or somesuch)
17:25
<viuo>
I want to skip re-evaluating B when doing a second iteration of A
17:25
<viuo>
so the eval MuExpr B set the state for B
17:26
prooftechnique joined
17:26
<ski>
(hm, `evalEmersonLei' is only defined in the `MuExpr' and `NuExpr' cases)
17:27
<* ski>
'd probably specialize that to `evalEmersonLeiMu' and `evalEmersonLeiNu'
17:27
<ski>
(or unfold, though the two bodies here are a bit large, so perhaps you wanted to avoid that)
17:28
<* ski>
is trying to get a feel for the structure
17:28
<viuo>
yeah, emerson lei is an extension of a basic naive algorithm
17:28
<Jinixt>
is it possible to build a list with do notation? adding one element at a time
17:29
<viuo>
they are only different in the muexpr and nuexpr cases
17:29
<Jinixt>
(preferably without eating the performance cost of appending at the end)
17:29
<* ski>
'd factor out the common parts of the `if' there
17:30
<viuo>
oh right, cause it's in a do block anyway
17:30
<ski>
Jinixt : "adding one element at a time" is not that often a good idea, when dealing with lists
17:30
<Jinixt>
yeah i know
17:30
<ski>
viuo : in this case, one could use `when'/`unless'
17:31
<Jinixt>
which is why i was hoping for something that would be statically transformed to something more performant
17:31
<ski>
> do y <- [4,9,16]; x <- [sqrt y,-sqrt y]; return (x,y)
17:31
<lambdabot>
[(2.0,4.0),(-2.0,4.0),(3.0,9.0),(-3.0,9.0),(4.0,16.0),(-4.0,16.0)]
17:32
<Jinixt>
imagine foo :: Int -> [Int], where if the argument is 0, you add an extra element to the middle of the list
17:32
<Jinixt>
which is otherwise constant
17:32
<ski>
to the middle of *which* list ?
17:32
<Jinixt>
a constant inside the function
17:33
<* ski>
is still not getting the picture
17:33
<okeuday_bak>
it appears that one hex format char in a string causes all chars to be interpreted as hex, is there a way to avoid that? e.g. "\x83d" become one character
17:33
<okeuday_bak>
it is likely attempting to make everything into UTF8
17:34
<Jinixt>
foo x = if x == 0 then [1, 2, 3] else [1, 3]
17:34
<Jinixt>
but without having to duplicate the list there and having more complex control flow etc
17:34
<Jinixt>
just a simple example
17:35
<ski>
> let x = 0 in concat [[1],if x == 0 then [2] else [],[3]]
17:35
<lambdabot>
[1,2,3]
17:35
<ski>
> let x = 1 in concat [[1],if x == 0 then [2] else [],[3]]
17:37
<Jinixt>
while that works it's not exactly what i'm looking for; i intend to try moving code from State to a DSL, where the DSL is just a list of a sum type
17:37
<Jinixt>
so there's more control flow going on
17:38
<ski>
yeah, elaborate on that ?
17:38
<Jenaf>
what was the function for (a->b->c)->(b->a->c) again?
17:38
<lambdabot>
(a -> b -> c) -> b -> a -> c
17:38
<ski>
@hoogle (a->b->c)->(b->a->c)
17:38
<lambdabot>
package base
17:38
<lambdabot>
package bytestring
17:38
<lambdabot>
package containers
17:38
<ski>
@hoogle (a -> b -> c) -> (b -> a -> c)
17:38
<lambdabot>
Prelude flip :: (a -> b -> c) -> b -> a -> c
17:38
<lambdabot>
Data.Function flip :: (a -> b -> c) -> b -> a -> c
17:38
<lambdabot>
CorePrelude flip :: (a -> b -> c) -> b -> a -> c
17:39
<* ski>
tries looking some more at viuo's code
17:39
<viuo>
im trying to formulate my problem properly
17:40
<* ski>
is trying to figure out why `evalEmersonLei' apparently is using some previously set value of `fp' in the state
17:40
<viuo>
take a look at fixPoint
17:41
<viuo>
it runs in a loop
17:41
<viuo>
each loop it's going to grow the Set or Shrink it
17:41
<ski>
yeah, but that's for handling one `MuExpr' (or `NuExpr')
17:42
<viuo>
yes but they can be nested
17:42
<viuo>
so e in fixpoint can be MuExpr also
17:42
<ski>
i'm not seeing why `evalEmersonLei' is somehow expecting `fp' to already have an associated value, before starting to process a `MuExpr'/`NuExpr' with a particular `fp' identifier
17:43
<ski>
surely something like MuExpr (FixedPoint 'A') (MuExpr (FixedPointExpr 'A') ...) isn't intendend -- or is it ?
17:43
<viuo>
for one because we initialize it at the beginning with iniEmersonLei
17:43
<viuo>
well with different values it is
17:43
<* ski>
hasn't seen `eval' calling `initEmersonLei'
17:43
<viuo>
sorry we initialize it at start in my main file
17:44
<viuo>
so MuExpr (FixedPoint 'A') (MuExpr (FixedPoint 'B') ... is completely legit
17:44
<ski>
(and, afaiac, i'm just consider a call like `runState (eval ...) (newEmersonLeiEnvironment ks)')
17:44
<ski>
yeah, but reusing the *same* identifier with two different (nested) `MuExpr' ?
17:44
<viuo>
runState (initEmersonLei f >>= eval ) (newEmersonLeiEnvironment kripke)
17:44
<Jinixt>
ski: essentially, i want to write imperative-like code because it makes sense when talking about state transformation, but i want the result to end up in a list as a sequence of commands (and not State because it lets you do "anything")
17:44
<Jinixt>
i think that's the best way to explain it
17:45
<viuo>
same identifier is not legal but I do not check for it
17:45
uglyfigurine joined
17:45
<viuo>
it's a university project after all
17:45
<ski>
Jinixt : it's still too vague to be able to give anything but very vague advice, and shots in the dark
17:46
<ski>
not checking for it is ok. i wanted to know whether it was allowed or not
17:46
<ski>
(by your precondition, i.e.)
17:47
<viuo>
ski: you can ignore what happens when b==Nu etc
17:48
<* ski>
would probably `initEmersonLei :: Expr -> Evaluator ()' ..
17:48
<viuo>
the core is in v <- lookUp fp and fixPoint fp l v
17:48
<Aruro>
why lense library occupies name space _Control_.Lense ? isnt it more _Data_.Lens?
17:48
<viuo>
every time we evaluate MuExpr we first check the value of the variable and feed it to fix point
17:48
<ski>
(or even `initEmersonLei :: Expr -> SymTab')
17:48
<viuo>
fixpoint will then run in a loop starting with this variable
17:49
<Jinixt>
it comes back to my earlier question about design of a card game. each Card can have a sequence of Effects (from a finite set of possible effects) depending on the current state of the board. while it's of course possible to write these cards as [Remove 0, Add "SomeCard"] or whatever, it sometimes has more control flow (depending on the board state), which would make do-notation handy
17:49
<viuo>
when it's done the variable should be set to the result
17:49
<Jinixt>
how about that
17:49
<ski>
Aruro : i suppose it's "control structures for *accessing* data" ?
17:50
<Aruro>
are setters and getters control structures?
17:50
<viuo>
since we basically have a nested loop when we have MuExpr inside MuExpr
17:50
<ski>
viuo : now i'm wondering if you really want to set the initial values in `initEmersonLei', and not rather just when you start processing `MuExpr' and `NuExpr'
17:50
<viuo>
we do not want to recalculate that
17:51
<ski>
viuo : since with nesting (and repeating of those constructs), you'll pick up the old value from the last outer iteration
17:51
<ski>
i'm wondering whether this is what you intended or not
17:51
<viuo>
exactly I don't want to do that
17:51
<ski>
<viuo> since we basically have a nested loop when we have MuExpr inside MuExpr
17:52
<viuo>
I want for inner loop to set the state of outer loop
17:52
<ski>
so you want the next activation of the inner loop to pick up the last value of the previous activision of the inner loop, correct ?
17:52
<viuo>
so in the second iteration of outer loop we do not start from 0 so to speak
17:52
<viuo>
sorry Im still confused by the fp
17:53
<monochrom>
Aruro: If you go through examples like Data.Set, Data.Map, Data.Vector, Data.Int... they are actual data or data structures, in which case lens is an odd man out.
17:54
<Aruro>
perhaps, but is it native of Control. set? :)
17:55
<Aruro>
somehow negating whole point of having meaningful module classes
17:56
<ski>
it's an "abstract" set, not particular to any data structure
17:56
<monochrom>
Bat.Lens. Also Bat.List.
17:59
<Aruro>
from same series, Data.Profunctor is it actually a data structure?
18:00
<monochrom>
No. You can also cite Data.Function and Data.Functor.
18:00
<ski>
viuo : sorry, i'm still not seeing the problem
18:01
<Aruro>
why not to bring then Function and Functors also to Control? :)
18:02
<Aruro>
Control.Profuntor sounds ok.
18:02
<monochrom>
Yes. Send a pull request.
18:02
<* ski>
. o O ( #haskell-lens )
18:04
<Clint>
Control.List
18:04
<ertes>
Aruro: at least having both Control and Data allowed 'lens' to use Control.Lens without conflicting with the older data-lens, which uses Data.Lens =)
18:04
<viuo>
ski: ok very simply in expression (X (Y)) i want to evaluate Y and set the current state of X to that of Y
18:04
<monochrom>
Oh, Data.Lens is already taken!
18:05
<ertes>
you think in lisp everything is data? you haven't seen van laarhoven lenses yet!
18:06
<monochrom>
lisp is too easy. car and cdr are the basic lenses (prisms?) and you just compose them for a complete suite.
18:07
<ski>
viuo : surely you don't want to set the state associated with `A' to the one associated with `B' in
18:07
<ski>
MuExpr (FixedPoint 'A') (MuExpr (FixedPointExpr 'B') (DiamondExpr 'action' (FixedPointExpr 'B')))
18:07
<* ski>
. o O ( `caddaadr')
18:07
<ertes>
you think in lisp everything is data? you haven't seen van laarhoven optics yet!
18:08
<viuo>
i want the assignment of B to be visible in A
18:08
<* ski>
thought each of the variables associated with individual `MuExpr's were to be kept distinct
18:09
<ski>
an assign 'B' ... won't affect a lookUp 'A'
18:09
<viuo>
the only reason why I want that is that evaluation runs in a loop
18:09
<viuo>
so MuExpr A will run a loop
18:09
<viuo>
and if in a loop there is a MuExpr B, i do not want to re-evaluate it
18:09
<* JuanDaugherty>
suspects a CL lens lib has just been referred to
18:10
<viuo>
in imperative it would be something like - have global map and set it
18:10
<viuo>
so if I have already iterated through B I can just read it
18:10
<ski>
that's what you're doing here as well, unless i'm missing something
18:11
<ski>
you have a single `SymTab'. using `assign' on `B' will update one part of it, using `lookUp' on `A' will read another, independent, part of it
18:11
<viuo>
yes but it's working only on the same level
18:11
<ski>
i don't see how this is any different from in an imperative language
18:11
<monochrom>
catmorphism :: (F r -> r) -> Meow F -> r
18:11
<viuo>
so so if we treat MuExpr as a loop
18:12
<viuo>
then A as an outer and B as inner
18:12
<viuo>
we loop A times B
18:12
<viuo>
each iteration of A we set be to some value
18:13
<viuo>
so we reset B each time we loop A
18:13
<viuo>
what I want is that first time we loop B we set B and in second iteration of A we get this B and not reset it
18:14
<ski>
i only see you calling `reset' when you switch from `Mu' to `Nu' and vice versa
18:14
<viuo>
no no that's a different thing
18:14
<viuo>
1. iteration of A :: 1 iteration of B -> B = {}
18:14
<viuo>
1. iteration of A :: 2 iteration of B -> B = {1}
18:15
<viuo>
1. iteration of A :: 3 iteration of B -> B = {1,2}
18:15
<viuo>
2. iteration of A :: 1 iteration of B -> B = {}
18:15
<viuo>
but I want it to be :
18:15
<viuo>
2. iteration of A :: 1 iteration of B -> B = {1,2}
18:15
<ski>
is that what you want, or what you observe ?
18:16
<viuo>
so I do not want to clear ( ;) not reset sorry ) B when continuing with A
18:16
<* ski>
is still thinking the problem must be elsewhere, not causing this code to run or something ..
18:17
<viuo>
I thought it's because I do result <- eval and then use this as a result
18:17
<ski>
actually, you don't set `fp' to the last value in `fixPoint'
18:17
<ski>
you're stuck and the next-to-last
18:17
<ski>
perhaps that's it ?
18:18
<* ski>
ought to have spotted this before
18:18
<viuo>
what would the best is to have something like (result, env) <- eval
18:18
<ski>
hm, or perhaps this doesn't matter anyway
18:19
<viuo>
that doesn't matter because it's the same
18:20
<viuo>
when evaluating I want to get both the result of evaluating the expression and the environment when it finishes
18:20
<viuo>
so (result, environment) <- eval l
18:20
<ski>
@type runState
18:20
<lambdabot>
State s a -> s -> (a, s)
18:20
<viuo>
and then do something like updateEnvironment env
18:21
<ski>
if you're still in `Evaluator', this shouldn't matter
18:22
<viuo>
there is something like reverse state monad i think right ?
18:22
<ski>
yes, but i can't imagine why you'd want it here
18:22
<Cale>
There is, but it sounds more like you want the ordinary one.
18:23
coup_de_shitlord joined
18:23
<Cale>
The one where the state travels backwards in time is weird and you almost never want it.
18:23
<ski>
(iirc, one use was backward AD)
18:24
coup_de_shitlor| joined
18:24
<viuo>
how is a global state in an expression usually done ?
18:24
<viuo>
imagine you have the old school "global" keyword
18:24
<* ski>
would like to get a concrete value for `kripke' in `runState (initEmersonLei f >>= eval ) (newEmersonLeiEnvironment kripke)', and expected vs. actual output
18:25
<viuo>
i want to be able to set a global variable basically
18:25
<ski>
the point isn't "global" state, it's just a matter of mutable state persisting far enough
18:26
<viuo>
hmm the state persisting far enought is not my problem
18:26
<ski>
(sufficiently nonlocal state, if you insist)
18:26
<viuo>
yeah something like this
18:27
<viuo>
if i have a nested expression that assings X=1 and after evaluating i'd do something like X+2 I want the result to be 3
18:27
<ski>
yeah, that's what `State' gives you, out-of-the-box
18:27
<viuo>
even if I have set X=0 in the beginning
18:27
<ski>
.. meaning that there must be something else here that we're missing
18:28
<ski>
as long as you don't rerun that `X := 0' assignment, you should be fine
18:28
<ski>
(but you only run `initEmersonLei' once, so shouldn't be a problem)
18:29
<viuo>
so It has to be something else
18:30
<ski>
that's my inference, yes
18:30
<viuo>
or nothing is wrong at all just it's the overhead of all the stuff I do in EmersonLei that screws it up
18:30
<viuo>
in theory emerson lei should waaay faster since it's not recalculating stuff
18:30
<viuo>
in practice it's always way slower in this case
18:31
<viuo>
since it returns correct result I just assumed it's resetting stuff
18:31
<ski>
(at this point, i'd start to check whether you've saved the file, whether you're compiling/running the correct code, &c. -- except that you seem experienced enough to already have checked all such silly mistakes already)
18:32
<* ski>
was under the impression that viuo was getting an incorrect result out of the computation, though
18:32
<viuo>
can you think of an easy way to log how the State changes with time ?
18:32
<viuo>
yeah sorry I did not specify that
18:33
<viuo>
the result is correct, I did a version without using monads and just passing everything in the arguments before
18:33
<ski>
use `State [Environment]', have the accessors, updaters, modifiers access the head element, make changes to the state actually push a new state on the list
18:33
<viuo>
the reason I switched to State Monad because I was under the impression that it's the best way to handle the global thingy
18:34
<ski>
it's a good way to avoid the boiler-plate (and bugproness) of explicitly threading the state around, yes
18:35
<viuo>
damn I could have gone with c++
18:35
<viuo>
well I did learn something though
18:36
<ski>
how did emerson lei fare with the version threading state around explicitly ?
18:36
<ski>
also slower in that case ?
18:36
<shapr>
ongy: got any other small complete Haskell projects you'd suggest?
18:37
<viuo>
but I that was exactly because I did not have a global variable
18:38
<viuo>
so it was doing I thought what was happening here
18:38
<ski>
all `State' does is hide the state-threading for you
18:38
<ski>
it's still passing it around, under the covers
18:39
<ski>
if you want to, you could try using `STRef s' or `IORef' instead
18:39
<ski>
which are implemented by actual update-in-place
18:39
<* ski>
isn't sure it would make much of a difference here
18:40
<viuo>
I think Im just going to give up for now
18:40
<ski>
@type newIORef
18:40
<ski>
@type readIORef
18:40
<lambdabot>
• Variable not in scope: newIORef
18:40
<lambdabot>
• Perhaps you meant ‘newSTRef’ (imported from Data.STRef)
18:40
<lambdabot>
• Variable not in scope: readIORef
18:40
<lambdabot>
• Perhaps you meant ‘readSTRef’ (imported from Data.STRef)
18:40
<ski>
newIORef :: a -> IO (IORef a)
18:40
<ski>
readIORef :: IORef a -> IO a
18:40
<viuo>
have a report due midnight anyway, spent way too much time trying to fix that anyway
18:40
<ski>
writeIORef :: IORef a -> a -> IO ()
18:40
<ski>
viuo : fair enough
18:41
<viuo>
I'll check changing Environment to [Environment] first though
18:41
<ski>
in C++ terms, these are more or less `p = new ...', `*p' and `*p = ...'
18:41
<viuo>
Thanks a lot for your time
18:42
<viuo>
how do I buy you a beer ;) ?
18:42
<ski>
hehe, i don't drink beer :)
18:43
<viuo>
well then In all cases thank you for clearing things out for me and for some remarks on my code. :)
18:44
<sdrodge>
Speaking of stateful computations. I'm trying to rewrite my program that is currently (flip evalState Empty . mapM doQuery) :: [Int -> Int] where doQuery is (State Blah Int)
18:44
<ski>
viuo : i could give more remarks on small things, but i was thinking it was more important to try to find the main problem you were having ..
18:44
<sdrodge>
To use pipes instead.
18:45
<sdrodge>
Anyone know how to do that easily?
18:45
<viuo>
ski: next time maybe then, I think I'll be getting some more into haskell
18:47
<ski>
viuo : apropos C++, Bartosz Milewski seem to have some YT videos about concepts in Haskell, in some cases applying them in C++
18:47
<sdrodge>
*(Int -> Int)
18:47
<sdrodge>
not a list of int functions, lol
18:47
<* ski>
was wondering ..
18:49
<sdrodge>
jesus, I mean [Int] -> [Int]
18:50
<* ski>
also guesses sdrodge meant a different type for `doQuery', perhaps `Int -> State Blah Int'
18:50
<ongy>
shapr: not really. Also I don't think it's a bad example. I have just seen it often lately :)
18:50
<sdrodge>
ski: You're right again.
18:50
<ongy>
my stuff is usually to much around FFI...
18:50
<sdrodge>
Geez I should not try to type this from memory while very tired.
18:51
<viuo>
ski: yeah I am familiar with him, there is a lot of awesome stuff he wrote, Im a bit tied up with some other things so I just went throught Learn you a haskell so far. Have to say that it's awesome to look at things from different perspective. Some things gave me a huge headache though. Type declaration of state monad being one of them :)
18:51
<* ski>
doesn't, alas, know much about `pipes', though
18:51
<sdrodge>
But basically, the program reads a list of ints in from a file, jams them through a state processor, and then writes the ints back out
18:51
<sdrodge>
but I want to do the I/O portion in a streaming manner
18:51
<sdrodge>
and I can't really figure out how to do it.
18:51
<sdrodge>
Because I am a pipes noob.
18:52
<ski>
viuo : some people think LYAH is like an hour-long trailer. iow doesn't give much depth (nor exercises)
18:52
<nitrix>
sdrodge: Without learning any pipe or fancy libraries, you can just leverage lazy lists.
18:52
<sdrodge>
nitrix: I don't think so, because of the mapM, right?
18:52
<ski>
@where CIS194
18:53
<ski>
viuo : *nod*. the main point is to get to know different approaches to things, to be able to have more choices when attacking a problem
18:53
<nitrix>
sdrodge: Ah yeah that's a problem.
18:54
<nitrix>
sdrodge: How about data Stream m a = Nil | Stream a (m (Stream m a)) ?
18:54
<nitrix>
Where Stream represents a value of type `a` and a generator for the next values of type `Stream m a` again.
18:54
<ski>
sdrodge : hm, with lazy `State', i think that could still be possible
18:55
<nitrix>
Until you reach Nil.
18:55
<sdrodge>
ski: mapM forces the whole list.
18:55
<nitrix>
Because of `sequence`, yeah. I've hit that problem a few times :P
18:56
<sdrodge>
nitrix: That's an interesting idea for sure.
18:56
<ski>
> (`evalState` 0) (mapM (\n -> state (\s -> (n ^ s,s+1))) (repeat 2)) -- `mapM' on an infinite list
18:56
<sdrodge>
I do want to try using pipes though.
18:56
<lambdabot>
[1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,2...
18:56
<ski>
not for `State s'
18:56
<nitrix>
ski: I believe the problem arise when you have `m ~ IO`.
18:57
<ski>
yes -- but i didn't suggest that
18:57
<nitrix>
I think he said the lists comes from a file or something.
18:57
<ski>
`hGetContents' ?
18:57
<monochrom>
I think we all agree what happens to IO's mapM. Just be careful when you generalize. Just don't generalize. :)
18:58
<sdrodge>
Interesting. TIL.
19:00
<sdrodge>
It's the same program I was asking questions about in here yesterday, btw.
19:00
<sdrodge>
https://hastebin.com/utamusoliq.hs
19:00
<* ski>
. o O ( "SSL error: error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error" )
19:00
<sdrodge>
Sounds like I drew unwarranted conclusions from the heap profile.
19:01
<sdrodge>
Because it shows memory usage only by main until peak memory usage, then a transfer out of main into doQuery and descendents for the rest of the lifetime of the program.
19:01
<sdrodge>
so I just assumed State's mapM was also forcing the list.
19:02
<sdrodge>
perhaps the real story is that IO's replicateM forces the entire list?
19:02
<ski>
well, it isn't
19:02
<ski>
but for `Maybe' and `Either e', it is
19:02
psychicist__ joined
19:03
<sdrodge>
Yeah, thanks for correcting my misconception.
19:03
<ski>
@src replicateM
19:03
<lambdabot>
replicateM n x = sequence (replicate n x)
19:03
<monochrom>
Yes, replicateM and mapM have similar behaviors in IO.
19:03
<ski>
`sequence' in `IO' traverses the whole list before relinguishinig control
19:04
<sdrodge>
So is there a simple change I could make to this program that would get me streaming I/O?
19:04
<monochrom>
unsafeInterleaveIO
19:04
<sdrodge>
okay, _other_ than that, lol
19:04
<ski>
`hGetContents' possibly
19:05
<ongy>
which is unsafeInterleaveIO
19:05
<* ski>
thinks `unsafeInterleaveIO' should possibly be renamed, in order to not unnecessarily scare people away from it
19:05
<monochrom>
I wouldn't say that. unsafeInterleaveIO is strictly much more general than hGetContent.
19:06
<ongy>
it has unsafeties, especially around withFile
19:07
<monochrom>
http://lpaste.net/77374
19:08
<* ski>
thinks calling `hClose' on a handle that's been passed to `hGetContents' ought to raise an exception
19:08
<ski>
(and similarly with calling `hGetContents' inside `withFile')
19:10
<sdrodge>
If I did want to rewrite this program using pipes, though, anyone know how I could go about it?
19:10
<emc2>
so, I have a situation where I have a Maybe-like type (named Result a; it has Success a, Undefined, and a few other failure modes). It has a straightforward Monad and MonadPlus instance
19:10
<emc2>
this is returned inside a monad
19:10
<emc2>
so functions like (MonadStuff m) => args -> m (Result a)
19:11
<dmwit_>
emc2: Without even seeing the rest of your question: you probably want `ExceptT`.
19:11
<emc2>
is there a pattern that can handle this nicely without having tons of case statements everywhere
19:11
<dmwit>
?unmtl ExceptT AllTheWaysItCanFail m a
19:11
<lambdabot>
ExceptT AllTheWaysItCanFail m a
19:11
<Rembane>
emc2: Check out the errors package, it is neat.
19:11
<dmwit>
?unmtl ErrorT AllTheWaysItCanFail m a
19:11
<lambdabot>
m (Either AllTheWaysItCanFail a)
19:11
<emc2>
obviously, if it was just Result, you can just use monad
19:12
<dmwit>
(\bot doesn't know about `ExceptT`; `ErrorT` has the same representation but possibly less preferable instances.)
19:12
<ski>
monochrom : great fun :)
19:15
<ski>
i especially like the Mordor one
19:15
<ski>
(simple, but suggestive)
19:17
<* ski>
idly wonders whether the `seq' there should use `pseq' or perhaps `evaluate' instead
19:20
<monochrom>
Yeah, but if it ain't broken, don't fix it :)
19:21
<ski>
the question is : is it broken ? :)
19:32
uglyfigurine joined
19:32
chaosmasttter joined
19:33
uglyfigurine joined
19:34
<ongy>
monochrom: that better than mordor... do I want to figure out why things happen that way?
19:34
<monochrom>
I don't know. Are you interested?
19:35
<* ski>
. o O ( concurrency is hard, .. )
19:35
<hololeap>
where is a good place to propose small changes to the containers package
19:36
<shapr>
ongy: ok, I'm convinced I need to write more small self-contained examples. I have one that turns off my touchpad with xinput, but I want to port that to turtle
19:36
<ski>
`chaosContent' is a bit similar to spawning two threads to `readTChan', collecting the results in whatever order they arrive
19:40
<ertes>
hololeap: the libraries mailing list
19:40
<ertes>
hololeap: also the issue tracker on github
19:41
<ertes>
hololeap: alternatively fork and implement the change, then issue a PR
19:44
<MarcelineVQ>
I believe containers has somewhat of a backlog atm so ymmv for response-time, the mailing list is probably the best spot for getting muliple eyes on your idea
19:46
<ertes>
i wish IntMap would get on par with HashMap… it was quite surprising to see that the latter is actually faster most of the time
19:48
<hololeap>
ertes: does it have a git repo or something?
19:48
<MarcelineVQ>
yes https://github.com/haskell/containers/issues
19:48
<hololeap>
oh, cool
19:49
<ongy>
shapr: that's a shell one-liner for me. maybe not that interesting
19:49
<ongy>
or do you have a nicer trigger for it?
19:50
<hololeap>
well, i might as well ask for input since it's a really small change. i thought that the drawTree and drawForest would be better to be implemented using Show instead of forcing the type to be Tree String
19:50
<hololeap>
(or Forest String)
19:50
<hololeap>
any reasons that wouldn't work?
19:51
psychicist__ joined
19:56
cereal_killer_ joined
19:58
<geekosaur>
Show is not the best thing to use for prettyprinting, since (a) ideally show . read ~~ id (b) it's really intended for debugging, not prettyprinting, so should include details you need to debug an error in the tree
20:01
MindlessDrone joined
20:01
epsilonhalbe joined
20:05
<MarcelineVQ>
I see so one should map an element-to-String function over the tree to use drawTree rather than relying on Show to reasonably show the things you're interested in, since it likely won't. You lose the ability to decide what's displayed with `Show a => a` compared to (a -> String)
20:09
<Denommus`>
intero is good. I like it
20:18
psychicist__ joined
20:23
psychicist__ joined
20:25
magneticduck joined
20:33
<mniip>
MarcelineVQ, well uh technically nah
20:34
initiumdoeslinux joined
20:34
<ezyang>
Man, IntMap is so fast lol
20:35
<mniip>
data Shown a s = Shown a; instance Reifies s String => Shown a s where show = reflect
20:37
<Denommus>
do we have a recommended regexp library already?
20:37
<ezyang>
don't use regex-compat!!
20:38
<Denommus>
ok, but what to use? XD
20:40
<ezyang>
don't use regex-posix either
20:40
<ezyang>
regex-tdfa is pretty common. regex is new kid on the block
20:40
<cdornan>
if you are set on PCRE then pcre-light or pcre-heavy are also possibilities
20:43
<cdornan>
regex is shim on regex-tdfa and regex-pcre -- will support either backend in the same framework
20:45
<MarcelineVQ>
mniip: I'm not sure what you're communicating to me :O
20:46
<cdornan>
the problem with regex-compat/regex-posix is that they rely on platform libraries which are buggy
20:47
uglyfigurine joined
20:47
<pikajude>
but regex-pcre doesn't work with ghcjs
20:47
<Denommus>
ok, why =~ needs [[String]] instead of [String]? I don't get it
20:48
<Denommus>
pikajude: I don't need ghcjs :-)
20:48
<pikajude>
oh, good
20:48
<maerwald>
cdornan: which ones?
20:48
<cdornan>
ok -- then you probably want regex-tdfa or regex
20:48
<cdornan>
(for ghcjs)
20:49
<cdornan>
why is regex using [re| ... |]?
20:50
<Denommus>
cdornan: probably because it's easier to write regexes that have backlashes
20:50
<cdornan>
so that we can check the REs are well formed at compile time
20:50
<cdornan>
and that too!
20:51
<Denommus>
cdornan: ah, that's cool
20:51
<Denommus>
but, again, why does =~ need [[String]] to extract multiple matches?
20:51
<Denommus>
why not [String]?
20:51
<mniip>
MarcelineVQ, reflection
20:52
<geekosaur>
Denommus, presumably because each match can have captures in it
20:52
<cdornan>
String type for RE isn't great either -- too easily confused with the text you are matching
20:52
<geekosaur>
so each match is a list of strings [whole match, capture 1, ...]
20:52
<cdornan>
but you can comoile from String anyway if you need to
20:53
<maerwald>
cdornan: which platform libraries are buggy?
20:53
<MarcelineVQ>
mniip: mmm, but why
20:53
<geekosaur>
aand you really don't want the result type to change based on whether the RE has captres or not
20:53
<cdornan>
macOS, Linux and Windows I think -- let me get the refernce
20:54
<geekosaur>
(in fact you can't since that's reliably determinable onlyat runtime)
20:57
<cdornan>
problems with regex-posix documented here: https://wiki.haskell.org/Regex_Posix
20:58
uglyfigurine joined
20:59
<cdornan>
no data on the Windows libraries there -- don't know about those
21:06
<johnw>
Profpatsch: what was the question?
21:09
<ertes>
captures are just a horrible hack anyway, because regexes don't support semantics
21:09
<ertes>
just use an actual parser library
21:12
<ertes>
regexes are in the same lines of "solutions" as SELinux: there is not a single legitimate use case, yet people love it for some reason
21:14
<cdornan>
well I haven't just been writing a regex library but have been making heavy use of them for the first time in my Haskell career -- I couldn't disagree more with the notion that captures are not useful (when properly supported) -- a big mistake IMHO
21:15
<ertes>
cdornan: captures are useful *with regex*… my claim is that regexes themselves are a bad idea
21:16
<ertes>
i can see how regexes are useful in a language like perl or PHP, but in haskell? we have a language that supports EDSLs properly
21:16
<cdornan>
as I said that in my experience is a major mistake -- regex captures don't make much sense without regexes
21:17
<chilversc>
I was looking at http://book.realworldhaskell.org/read/defining-types-streamlining-functions.html#Tree.hs:simpleTree and wondered if I could define a constructor Leaf a that is equivilent to Node a Empty Empty?
21:19
<nitrix>
chilversc: data Tree a = Empty | Leaf a | Node a (Tree a) (Tree a) ?
21:19
<geekosaur>
only if you rewrite everything to use it. unless you want to get into the (more recent than RWH by several years) pattern synonyms extension
21:20
<chilversc>
nitrix: but wouldn't treat Node 5 Empty Empty as being different to Leaf 5?
21:20
<geekosaur>
yes, it would
21:20
<nitrix>
chilversc: For the purpose of pattern matching, yes. I just thought you could handle both cases.
21:21
<nitrix>
pattern Lead a = Node a (Tree a) (Tree a)
21:21
<pikajude>
pattern Leaf a = Node a Empty Empty
21:21
<nitrix>
Oh sorry, Empty yeah
21:21
<geekosaur>
^ pattern synonyms extension
21:21
<geekosaur>
these can be bidirectional, meaning they can lso behave as "virtual constructors"
21:22
<nitrix>
@let data Tree a = Empty | Node a (Tree a) (Tree a)
21:22
<lambdabot>
.L.hs:162:23: error:
21:22
<lambdabot>
Ambiguous occurrence ‘Tree’
21:22
<lambdabot>
It could refer to either ‘Data.Tree.Tree’,
21:22
<nitrix>
@let data MyTree a = Empty | Node a (MyTree a) (MyTree a)
21:22
<lambdabot>
Defined.
21:22
<nitrix>
@let pattern Leaf a = Node a Empty Empty
21:22
<lambdabot>
.L.hs:165:9: error: Not in scope: data constructor ‘Leaf’
21:22
<lambdabot>
.L.hs:165:18: error:
21:22
<geekosaur>
no patsyns in lambdabot currently I think
21:23
<nitrix>
geekosaur: https://github.com/lambdabot/lambdabot/blob/freenode/lambdabot/State/Pristine.hs.708
21:23
<nitrix>
Looks like it :(
21:23
<nitrix>
I wonder why.
21:23
<chilversc>
geekosaur: interesting, but as standard the answer is no? though I guess I could just have leaf a = Node a Empty Empty
21:24
<geekosaur>
nobody requested it yet? talk to int-e I think
21:24
<pikajude>
since it's bidirectional you can also use `Leaf foo` as an expression
21:24
<geekosaur>
chilversc, you cannot "define a constructor" that way except as part of the data type, in which case it is distinct (can't resolve to Node a Empty Empty)
21:25
<geekosaur>
you can define a *function* that way but you then can't use it in a pattern
21:25
mizu_no_oto_work joined
21:25
<noobsy>
hey guys, if I have a String, how do I view this as a char array and see what the first letter of the word is?
21:25
<nitrix>
I think there's PatternGuards too?
21:25
<pikajude>
pattern guards came first right
21:25
<noobsy>
could I just do (first String)?
21:25
<geekosaur>
:t head
21:25
<nitrix>
noobsy: type String = [Char], it already is a list of chars.
21:25
<lambdabot>
[a] -> a
21:26
<nitrix>
noobsy: head :: [a] -> a
21:26
<noobsy>
so say I have a string b
21:26
<noobsy>
I can do (head b) and that gives me the first character
21:26
<cocreature>
assuming a first character exists :)
21:26
<geekosaur>
yes, there's pattern guards and view patterns and various other things, but you can;t just pretend it's a constructor. that's why patsyns exist
21:26
<geekosaur>
re Leaf
21:27
<noobsy>
another thing is I want to check to see if this first character is a member of accepted characters
21:27
<noobsy>
for example, vowels
21:27
<noobsy>
is there any way I can do that without doing a whole bunch of ifs?
21:27
<pikajude>
elem "aoeui"
21:27
<nitrix>
noobsy: `elems` "aeiouy"
21:27
<pikajude>
:t elems
21:27
<lambdabot>
Array i e -> [e]
21:27
<cocreature>
> 1 `elem` [1,2,3]
21:27
<pikajude>
that sounds wrong
21:28
<cocreature>
> 4 `elem` [1,2,3]
21:28
<pikajude>
@let isVowel = (`elem` "aeiou")
21:28
<lambdabot>
Defined.
21:28
<cocreature>
^ noobsy that’s probably what you’re looking for
21:28
<nitrix>
Seems like `elems` is the version for Data.Map and similar. Don't mind the `s` then.
21:28
<noobsy>
how would that look, if (head String 'elem' "aeiou") then ___ else ___?
21:28
<cocreature>
noobsy: you need backticks not '
21:28
<nitrix>
noobsy: Close, but you'd need backticks, not apostrophe.
21:29
<noobsy>
alright, thanks
21:29
<cocreature>
also in most cases, pattern matching is better than using head since you can handle the case where the string is empty
21:29
<pikajude>
let foo (x:_) | isVowel x = myFunction; foo _ = error "doesn't start with vowel"
21:30
<noobsy>
so like case?
21:30
<pikajude>
they both support patterns
21:30
<noobsy>
case [] do nothing, case x:xs, evaluate on x?
21:30
<nitrix>
case lets you pattern match too, yeah.
21:31
<nitrix>
noobsy: It matches the pattern x:xs if it can, otherwise fallthrough the other cases. Evaluation is something else entirely.
21:31
<noobsy>
when I mean evaluate I meant evaluating if it's a vowel or not
21:32
<cocreature>
case "a" of [] -> "empty string"; (c:cs) -> "single character" ++ show c
21:32
<cocreature>
> case "a" of [] -> "empty string"; (c:cs) -> "single character" ++ show c
21:32
<lambdabot>
"single character'a'"
21:32
<cocreature>
> case "" of [] -> "empty string"; (c:cs) -> "single character" ++ show c
21:32
<nitrix>
In this case, there is evaluation happening, it's not wrong, just that I think the word you intend to use is `verify`/`check` or even `predicate`.
21:32
<lambdabot>
"empty string"
21:34
<akr[m]>
Hi there, so I'm supposed to get a cabal project building and it's got the whole dependency hell thing going on… There is some patched package optparse-applicative included whose version has been set to 10000.something, but there is also a dependency fay, forced at some specific version, which requires optparse-applicative under 0.5… I guess my question is, how could this have ever worked?
21:34
<merijn>
akr[m]: My guess is "it didn't"
21:35
^SpOOn^r4a8p7 joined
21:35
<qqwy>
Hello, everyone!
21:35
<nitrix>
noobsy: We try to keep the term evaluation for when we mean some of Haskell's operational semantics (typically in the context of lazy evaluation, which is something Haskell differs from other functional languages).
21:35
<merijn>
akr[m]: Because that sounds like an incredibly shittily maintained package at first glance
21:35
<eacameron>
Is it possible to derive a QuickCheck Arbitrary instance for a Generic type?
21:36
<akr[m]>
merijn: well, someone managed to launch it into production - although that might have been before someone else came around and try to "fix" things
21:37
<merijn>
akr[m]: Well, if it didn't have proper upper bounds it might have worked then
21:37
<merijn>
akr[m]: But the lack of bounds might now result in cabal selecting some other set of versions that happen to not work out
21:37
<qqwy>
If you have a list-of-lists with the following preconditions: 1) each sublist is in increasing order, 2) when taking the heads of all sublists, this is in increasing order
21:38
<qqwy>
How can you then combine this to a single, flat, ordered list?
21:38
<nitrix>
int-e: Can we get -XPatternSynonyms for lambdabot's freenode default Prestine? Should I open a pull request?
21:38
<augur>
@where calcfp
21:38
<qqwy>
(as efficiently as possible)
21:38
<akr[m]>
merijn: but the package that requires optparse-applicative < 0.5 is fey == something
21:39
<akr[m]>
so I don't see how the bound could've changed
21:39
<qqwy>
This algorithm works, but is probably relatively inefficient:
21:39
<qqwy>
inOrder :: Eq a => [[a]] -> [a]
21:39
<qqwy>
inOrder [] = []
21:39
<qqwy>
inOrder ([] : rest) = inOrder rest
21:39
<qqwy>
inOrder ((x : fl_rest) : rest) = x : ((concat xes) ++ (inOrder xless_rest))
21:39
<qqwy>
(xes, xless_rest) = unzip $ map (\list -> span (== x) list) (fl_rest : rest)
21:40
<qqwy>
Is there a smarter way?
21:41
<merijn>
akr[m]: Perhaps, it's hard to say like this
21:41
<merijn>
akr[m]: I don't suppose tracking down the original maintainer and giving them a swift beating is an option?
21:42
<akr[m]>
well, they do have their names in the commits
21:42
<ertes>
cdornan: that's not what i meant… a proper parsing abstraction allows you to abstract and to encode semantics within the parser: Email <$> userName <*> char '@' *> domainName
21:42
<merijn>
ertes: ಠ_ಠ What if my email has no @ ?!?
21:43
<nitrix>
qqwy: Would you be able to rewrite it without that ++ ?
21:43
<pikajude>
it's not an email then
21:43
<lyxia>
qqwy: what about the other elements than the heads? how do they compare to each other
21:43
<ertes>
merijn: then it's not an email according to that particular parser =)
21:43
<merijn>
ertes: That means your parser is wrong!
21:43
<pikajude>
"what's your email?" "q"
21:43
<ertes>
merijn: maybe, but that's not the point
21:44
<merijn>
ertes: I know, but I'm tired and bored and thus contrarian :)
21:44
<geekosaur>
...that means local domain
21:44
<merijn>
pikajude: No, but a bang path is still technically valid
21:44
<pikajude>
i've never traveled a bang path
21:44
<merijn>
Technically yes, I wouldn't be surprised if half the infrastructure no longer supports it, though
21:45
<geekosaur>
(and things like bang paths, decnet ::, etc. will be resolved to local inet domain and then processed as mail to a locally reachable non-inet destination, provided the local mail handler supports that and/or can route to it)
21:45
<merijn>
pikajude: Hell, did you know valid emails can contain newlines?
21:45
<ertes>
merijn: i'd take the bait, but i have to go in a few minutes, sorry =)
21:45
<pikajude>
merijn: to the best of my knowledge (up until 3 minutes ago) it's a valid email address if there's a @ in it
21:45
Lord_of_Life joined
21:45
<pikajude>
well, specifically one @
21:45
<akr[m]>
merijn: so would there happen to be some tool which would attempt to find some assignment of versions such that everything is satisfied
21:45
<MarcelineVQ>
qqwy: I'd probably just concat and sort
21:45
<geekosaur>
even that is wrong
21:45
<pikajude>
that's why i said up until 3 minutes ago
21:46
<geekosaur>
source routing, although for spam reasons that's usually disabled
21:46
<pikajude>
a valid email is any string
21:46
<geekosaur>
@foo,@bar:bax@quux.org
21:46
<lambdabot>
Unknown command, try @list
21:46
<qqwy>
lyxia: They are in ascending order
21:46
<cdornan>
ertes: but a good regex library lets you do loads of stuff without having to set up abstractions -- just look at the tons and tons of applications of regex in regex-examples
21:46
<qqwy>
example_list = [
21:46
<qqwy>
[1,1,2,3,4,5,6],
21:46
<qqwy>
[1,1,1,3,5],
21:46
<merijn>
akr[m]: Well, the problem is not "finding such an assignment", it's "finding one that does AND actually works (in the sense of compiles and with the right behaviour)
21:46
<qqwy>
[2,2,2,3,3,3,6],
21:46
<geekosaur>
qqwy, please use a paste site
21:46
<lambdabot>
Haskell pastebin: http://lpaste.net/
21:47
<nitrix>
qqwy: Just to understand, [[1,3,7], [2,5,8], [4,6,9]] is valid?
21:47
<qqwy>
nitrix: Yes, it is
21:47
<cdornan>
if I want to just rip out the target from the output of a stack invocation then I don't want to have to set up a parsing abstraction, etc.
21:47
<lyxia>
qqwy: what about [[1,3],[1,2]]
21:47
<merijn>
akr[m]: My approach would be to basically strip all bounds, see if it finds a solution (probably it will) see where it fails to compile (it probably will) and figure out which version of the library it fails on changed the external API, then fix that bound to that version. Repeat until everything works
21:47
<merijn>
akr[m]: It'll be a hassle, though
21:49
<akr[m]>
merijn: yeah, doesn't sound like much fun… not even getting payed for this until I get it building
21:49
<merijn>
akr[m]: Nope, dependency management is never fun
21:50
<qqwy>
The example that nitrix gave is at least not correctly converted with the algorithm I posted
21:50
<nitrix>
qqwy: I'm working on an implementation for fun.
21:50
<merijn>
akr[m]: On the bright side, at least you'll GET compiler errors. If this was python/JS you wouldn't figure out if the dependency was changed incompatibly until runtime
21:50
<cdornan>
regex-examples is for the most part real scripts used to build the library, manage versions, build the cabal file from templates, the website, a test suite from the tutorial -- REs are really, really, really useful for all of this -- makes no sense to use parsers
21:51
<MarcelineVQ>
akr[m]: cabal has an option called --allow-newer that may be helpful to get going http://cabal.readthedocs.io/en/latest/installing-packages.html?highlight=allow%20newer#cmdoption-setup-configure-allow-newer
21:51
<eacameron>
Does anyone derive their Arbitrary instances with Generics? I have a simple record type which really just needs to stick "arbitrary" into every field.
21:51
<qqwy>
The idea is that the list-of-lists is generated by taking a list of (x,y) coordinates, taking the 'tails' of that, and for each of this [coordinate, other_coordinates] sublist, calculate the slope.
21:51
<qqwy>
Now you have a list-of-lists of slopes
21:51
<akr[m]>
MarcelineVQ: will try, thank you
21:52
<qqwy>
because of 'tails', this is ordered (the original list of coordinates was ordered)
21:52
<qqwy>
and because the slopes are created from these ordered lists, these will also be ordered
21:52
<merijn>
akr[m]: Well, --allow-newer basically just tells it to ignore upper bounds, so it's roughly what I recommend (a bit smarter, tbh, since it keeps the lower bounds intact)
21:53
<qqwy>
so I think you then end up with a list-of-lists where all sublists are ordered and the earlier elements of lower lists are never higher than the elements of later lists at the same index
21:53
<qqwy>
although I am not entirely sure
21:53
<qqwy>
(Which is why I asked this question)
21:53
<qqwy>
nitrix: Awesome! :D
21:55
<noobsy>
hey guys, assuming in this example "probOfSents" is just a function for finding the probability of something occuring given a certain model, is this the correct way to represent (probability modelVowel)(weight) + (probability modelLength)(1.0-weight)?
21:55
<noobsy>
http://pastebin.com/Juv5McFC
21:56
<akr[m]>
hmm, I can't find any docs on what does the fpath do in 'cabal install -fpath', anyone has any idea?
21:56
<noobsy>
or do I have to use fromIntegral?
21:56
<MarcelineVQ>
akr[m]: it sets a flag called path that is relevant to one of your .cabal files
21:57
<MarcelineVQ>
iow it'll be defined in one of them so you should be able to find it there
21:58
<Profpatsch>
johnw: It’s pretty awesome to construct stuff with hnix
21:58
<akr[m]>
there are flags there, but this is not one of them
21:58
psychicist__ joined
21:58
<Profpatsch>
But when matching against deep NExprs, there’s a lot of Fix going on.
21:58
<Profpatsch>
Maybe.
21:59
<Profpatsch>
Maybe I just don’t know what I’m doing and I can use ana/cata/hylo somehow.
21:59
<Profpatsch>
Practical example:
21:59
<Profpatsch>
outerLayer (Fix (NWith _
21:59
<Profpatsch>
(Fix (NWith _
21:59
<Profpatsch>
(Fix (NRecSet attrs)))))) = mkNonRecSet attrs
21:59
<dmwit>
akr[m]: Don't forget to look in the cabal files of packages in your dependency tree.
22:00
<jle`>
noobsy: you don't need to write 1.0
22:00
<jle`>
but other than that i am not sure what you're asking
22:01
<akr[m]>
dmwit: ah good point, thank you
22:02
<akr[m]>
nope, nowhere to be seen
22:02
<jle`>
this library is hilarious https://hackage.haskell.org/package/acme-smuggler
22:03
<jle`>
doesn't work if you pattern match on () though, which i guess fits into the metaphor/abstraction of the package (catching smugglers)
22:04
<jle`>
but who pattern matches on () anyway
22:04
<dmwit>
Apparently it's easy to catch a smuggler if you observe them a little bit.
22:05
<jle`>
hiding things in plain sight and just hoping nobody looks too closely
22:05
<dmwit>
unsafeCoerce (4 :: Integer) :: () -- = ()
22:05
<dmwit>
unsafeCoerce (unsafeCoerce (4 :: Integer) :: ()) :: Integer -- = 4
22:06
<dmwit>
I think we can make a v2 of this package which makes smugglers much harder to catch.
22:07
<jle`>
does that work if you pattern match on () ?
22:07
<dmwit>
Well, it printed out. So.
22:07
<jle`>
yeah it does :o
22:08
<dmwit>
However, this version is much unsafer. If you try to discover a non-smuggler, bad things happen.
22:08
<jle`>
gotta keep our smuggling operations safe
22:10
<dmwit>
smuggle :: Typeable a => a -> (); smuggle = unsafeCoerce . toDyn; discover :: Typeable a => () -> Maybe a; discover = fromDynamic . unsafeCoerce
22:10
<MarcelineVQ>
nitrix: got it?
22:10
<dmwit>
Then `smuggle 3` prints `()` and `discover it :: Maybe Integer` gives `Just 3`. =D
22:10
<nitrix>
MarcelineVQ: Got distracted, one sec.
22:11
<dmwit>
`discover () :: Maybe Integer` -> segfault =)
22:12
<johnw>
Profpatsch: we can fix that with pattern synonyms
22:12
<johnw>
Profpatsch: I just haven't done it yet
22:12
<johnw>
Profpatsch: example of what I mean: https://github.com/jwiegley/notes/blob/master/haskell/Synonyms.hs
22:13
<Profpatsch>
johnw: I have a comment like that:
22:13
<Profpatsch>
-- e.g. findBinding (StaticKey "a") [nix|inherit a b c;] -> [nix|inherit a;]
22:13
<Profpatsch>
I’d relly love quasiquotes.
22:13
<johnw>
yes, we should do that as well
22:13
<Profpatsch>
I think that would make it even cooler.
22:13
<johnw>
making a note...
22:14
<Profpatsch>
johnw: What’s the advantage of using the Data.Fix style of recursion?
22:14
<Profpatsch>
For hnix in particular?
22:15
<johnw>
it just makes the evaluators easier to write, since they can now be non-recursive
22:15
<Profpatsch>
The error messages are more confusing, I’m not sure if there are that many pros from closing the recursion in the first place.
22:15
<johnw>
and gives us a few other tools
22:15
<Profpatsch>
Hm, that’s interesting.
22:15
<johnw>
I could probably be convinced to convert to a form that doesn't use Fix
22:15
<Profpatsch>
I’m not entirely sure how (and for what) to use ana/cata/hylo.
22:15
<johnw>
once we have the pattern synonyms in place, it will become a purely internal detail anyway
22:15
<johnw>
so the switch will have zero impact on clients
22:16
<Profpatsch>
Maybe there’s an awesome usage I haven’t seen yet.
22:16
<johnw>
oh, and Fix let you create attribute grammars easily
22:16
<johnw>
because you can plumb other details through the recursive structure
22:16
<Profpatsch>
Hm, if the * -> * interface changed to * a lot of type signatures would break.
22:17
<Profpatsch>
I’m sure the algebra approach is the right one, yes.
22:17
<Profpatsch>
Just not there yet from an end-user perspective.
22:17
<Profpatsch>
Ah, that’s what Ann does?
22:17
<johnw>
Profpatsch: https://github.com/jwiegley/hnix/issues/52
22:17
<johnw>
Profpatsch: exactly
22:18
<johnw>
really the value of Fix is that the recursive structure becomes a detail you can play with outside of the core type
22:18
<johnw>
once you bake the structure in, you do gain simplicity benefits, but at the cost of flexibility
22:18
<Profpatsch>
The base toolbox should be as general as possible. As long as it’s possible to wrap it in a more user-friendly way.
22:19
<johnw>
yeah, we should be able to eliminate Fix from user view
22:19
<johnw>
although, I'm not entirely sure about the error messages...
22:19
<Profpatsch>
Right now what’s missing the most is a tutorial I think.
22:20
<Profpatsch>
I’m working on finding out how to best use the library myself, but maybe I can write something once I’ve used it a bit.
22:20
<akr[m]>
can I force cabal to install a specific revision of some version of some package?
22:20
<johnw>
Profpatsch: the synonyms fix should be dead simple (in fact, I'm thinking about writing a TH library for auto-generated such synonyms for any F-algebra)
22:21
<Profpatsch>
Something like that would be awesome, yes.
22:21
<Profpatsch>
It’s interesting that the Show instance of Data.Fix just outputs the structure with no Fixes.
22:21
<nitrix>
qqwy: MarcelineVQ: Lame. The scratch pad I was using expired :(
22:21
<Profpatsch>
Wait, I wonder if it’s possible to Read it in again that way.
22:21
<nitrix>
I'll give another shot tonight :P
22:22
<Profpatsch>
But even using the mkX functions is already awesome to generate nix expressions.
22:22
<Profpatsch>
https://twitter.com/Profpatsch/status/839315463221948416
22:23
<nitrix>
qqwy: My idea was to get the head of each list, find the `minimum` of that, keep it, then process the remainder of the lists recursively, without the minimum value we found.
22:23
<nitrix>
qqwy: Eventually some lists gets empty and can be discarded until we end up with no lists at all, in which case, we have everything sorted.
22:24
<nitrix>
qqwy: But a quick check revealed this is flawed :)
22:24
<johnw>
Profpatsch: yeah, quasi-quoting would be awesome :)
22:24
<qqwy>
Thank you for your help, nitrix!
22:25
<nitrix>
qqwy: The problem arises because you do not know if the maximum value of a given list falls into the range of another list.
22:25
<nitrix>
qqwy: So you cannot restrict yourself to the first N elements to each list, you have to merge them all.
22:25
<AWizzArd>
One nice aspect about purity is: when I generate tons of random data, I only need to store the commit hash of my repo, and the used seed as a resort of storing a „backup” of the data.
22:25
<nitrix>
qqwy: (1) Concatenate everything. (2) Sort everything. That's my best bet :)
22:26
<qqwy>
^^' Yes, that is the easy way
22:26
JeanCarloMachado joined
22:26
<nitrix>
It's also the only way without more invariants :/
22:26
<qqwy>
I was hoping that the current invariants would be enough to allow for an algorithm that runs faster than n log n.
22:27
<qqwy>
that is, n² * log(n²) when you consider `n` the amount of points whose slope-combinations you want to work with.
22:28
<qqwy>
I had hoped that sorting the points first, before generating their slopes would allow for a faster algorithm
22:29
<Profpatsch>
johnw: Oh, there was another screenshot from earlier https://twitter.com/Profpatsch/status/835646875822919684
22:30
<Profpatsch>
Seeing if I could translate an expression directly.
22:30
<nitrix>
qqwy: What I'm saying makes no sense.
22:31
<nitrix>
qqwy: I keep vizualizing multiple stacks and I keep thinking you can pick the top element from the appropriate stack and come up with a sorted list.
22:33
<nitrix>
qqwy: But that means given M lists of N elements, you perform N * M checks? Maybe not, if the lists are kept in a sorted fashion and the list you pick from is resorted.
22:34
<nitrix>
(e.g. lists A, B and C, with the top elements 1, 4, 7, you pick 1 from the list A, the value below is 5, then you resort your lists 4, 5, 7.
22:35
<nitrix>
And you keep doing that and picking from A, with a large amount of lists, it should give you a reasonable complexity...
22:36
<nitrix>
n * log(m) actually.
22:38
psychicist__ joined
22:38
<graygray>
Sorry if this sounds stupid but how would I go about adding a value to a list then returning a String as I was getting errors trying to use do
22:39
<Profpatsch>
graygray: val : list
22:39
<Profpatsch>
graygray: Code?
22:40
<graygray>
Profpatsch: I am using that to add to the list but then after that I was after a return string along the line of "Value added to List"
22:40
<Profpatsch>
graygray: would need to see the code
22:40
<nitrix>
graygray: do { modify (val:); return "added!" } ?
22:41
<graygray>
I can try that
22:41
<nitrix>
graygray: I need more context. What does your "modifying" implies? Is it a state?
22:42
<qqwy>
I am thinking about something like:
22:42
<qqwy>
1) take the first element from the first list
22:42
<qqwy>
2) take the next element from this first list as long as it is equal to the first
22:42
<nitrix>
qqwy: 2) Reposition the list once you see the second element of the list you just taken an element from?
22:43
<nitrix>
qqwy: Well you have to make sure it's still smaller than the top element of all the other lists everytime.
22:43
<nitrix>
qqwy: Keeping the lists sorted helps with that, but that means everytime you pick, you must resort at least the list you picked from.
22:43
<nitrix>
qqwy: That's what I tought too, but I get m * log n
22:44
<nitrix>
Where m is the amount of elements to pick and log n, the length of one list
22:45
<graygray>
nitrix: Profpatsch: http://collabedit.com/yh5f5 this is the context
22:46
<Profpatsch>
graygray: fan : (fans film) has which type?
22:46
<graygray>
data Film = Film {title :: String, director:: String, year:: Int, fans :: [String]} deriving (Read, Show, Eq)
22:47
<graygray>
fan is just a String
22:47
<Profpatsch>
graygray: So fan : fans is of type [String]
22:47
<Profpatsch>
But: you are in a do-Block
22:47
<Profpatsch>
What do you want to “do” in the do-Block? :)
22:48
<Profpatsch>
Probably IO
22:48
<qqwy>
But what if you wouldn't need to reposition, but iterate in order over the list-of-lists until it is empty: take from the first list until its head is > than the head of the next list. Then this first list is done for this iteration, and we go on to the next. When the last list is reached, we start again at the first one of the accumulated result (the list-of-lists without all elements we just removed). Rinse and repeat.
22:48
<graygray>
Profpatsch: Yeah, I am kind of new I know do is for IO but I'm not sure how I would get around doing multiple functions in that guard without do
22:48
<qqwy>
I am not sure if this will be possible, or if it needs more invariants
22:48
<Profpatsch>
graygray: What do you want the function to return?
22:48
<graygray>
Profpatsch: "Fan added to film's fanlist"
22:49
<Profpatsch>
Wait, is that what you want it to print as side-effect, or do you want the function to actually return it?
22:49
<graygray>
I want it to print as a side-effect
22:51
<graygray>
So, any ideas on how I would go about that
22:52
<Profpatsch>
graygray: I edited the code a bit.
22:52
<Profpatsch>
addFanReturnMessage is how you would do it if you wanted to return the message from the function.
22:52
<Profpatsch>
You just use a Tuple.
22:52
<Profpatsch>
But that’s not really sensible if you want to log to stdout what you are doing.
22:53
<nitrix>
qqwy: I think there's a problem because you can't always be picking from the first list and comparing with the other lists.
22:53
<Profpatsch>
So there’s the third function.
22:53
<nitrix>
qqwy: The top element of the first list might be bigger than the top of that of the other lists.
22:54
<nitrix>
qqwy: e.g. [[1,100], [2,5,7], [3,4]]
22:55
<nitrix>
qqwy: Everytime you pick, gotta resort the lists :)
22:55
<nitrix>
(The resorting is log m, and you'll be picking n times, n * log m).
22:58
<qqwy>
nitrix: Let me try to write my new idea out in an algorithm...
22:59
<qqwy>
Although, yes, you're right
22:59
<qqwy>
for input cases such as the one you just posted, that would not work
22:59
<qqwy>
I wonder if I am missing something
23:00
<qqwy>
There might be more invariants given from the input in my specific problem
23:01
<qqwy>
Right now I am writing a program that should, given a list of (x, y) coordinate points, print ot how many parallel lines there are
23:02
<qqwy>
That means that for all `n` points, a list containing every (`n * n-1`) _pair_ of points is made, and each pair is then converted into a (x1 - x2 / y1 - y2) rational number representing the slope.
23:02
<qqwy>
(This rational number is ofc. simplified so we can compare e.g. 1/2 with 2/4 properly)
23:03
<qqwy>
Now, to find out how many parallel lines there are is the same as finding out how many pairs have the same slope. You can however only find this out by sorting the list of slopes (and then counting adjacent equal elements), or alternatively building a hashmap-histogram from them.
23:03
<nitrix>
That sounds like linear algebra. You just get the slope of them all and find duplicates :P ?
23:04
<qqwy>
It's an exercise for Algorithms and Datastructures at the university. Which we are allowed to solve using Haskell B-)
23:04
<qqwy>
That is, the exercise itself I have solved
23:04
<qqwy>
but my program runs in O(n² * log(n²))
23:04
<noobsy>
can anyone help me with this? http://pastebin.com/WDti0xnM
23:04
<noobsy>
my compiler gives me an error
23:05
<qqwy>
as it first creates all slopes, and then sorts them
23:05
<nitrix>
qqwy: I have another approach.
23:05
<noobsy>
Couldn't match expected type (String, String) -> Double with actual type Double. Possible cause: (*) is applied to too many arguments, IN the first argument of probOfSents, namely (fromIntegral (bigramProbByLength modelLength) * weight) ...
23:05
<qqwy>
but what I am wondering about, is if it is possible to sort them faster than `n² log(n²)` by sorting the points before creating point-pairs and turning those into slopes
23:05
<nitrix>
qqwy: How about a `Map Slope Count` ?
23:06
<qqwy>
nitrix: That has the same time complexity
23:06
<qqwy>
Building a HashMap takes `log n` insertion time, which you do `n` times when converting a list to a HashMap.
23:07
<nitrix>
qqwy: Bloomfilters!
23:07
<noobsy>
my question is "weight" is a double, and the value returned by "bigramProbByLength" is a double, so why can I not just use arithmetic in there?
23:07
<qqwy>
My current solution uses a `Map Slope Count`, but I also have tried the `countAdjacents $ sort slopes` method
23:07
<qqwy>
Probabilistic data structures for the win
23:08
<qqwy>
It's really too unfortunate that my input data is too large for an IntMap
23:08
<qqwy>
it's so amazing that Patricia trees work in O(min(n, 64)) on 64-bit machines
23:08
<nitrix>
qqwy: I think bloomfilters would help here, avoiding unecessary lookups in the map.
23:09
<nitrix>
qqwy: Now that I think about it, you don't even need a map, a Set is enough.
23:09
<nitrix>
qqwy: All you care is if the element has been seen before, because that means you now have a new pair.
23:09
<nitrix>
qqwy: Or do you need to know which lines are paired together?
23:10
<qqwy>
You're right
23:11
<qqwy>
The actual program is slightly more involved and does need you to keep track of how many there are for each slope, as you want the amount of trapeziums you can make, i.e. the amount of combinations of _pairs_ of parallel lines.
23:11
<qqwy>
but the exercise itself does not change because of that
23:11
<qqwy>
it only is a single extra step at the end
23:11
<lyxia>
noobsy: you gave bigramProbByLength only one argument
23:11
<qqwy>
that converts `count` to 'count * (count-1) `div` 2'
23:11
<nitrix>
qqwy: Gotcha. I'm out of options then. I think bloomfilters is the furthest you can get.
23:12
<qqwy>
Thank you for your help :-)
23:12
<lyxia>
noobsy: so it gives you (String, String) -> Double, not just a Double
23:13
<noobsy>
so there is no way I can make this work then?
23:13
<noobsy>
given if I cannot touch any of the other functions
23:13
<noobsy>
besides trainTestInterpolated
23:14
<lyxia>
"make this work" is pretty vague
23:14
<lyxia>
I can see a way to make this compile
23:14
<lyxia>
I have no idea what this code does though
23:15
<lyxia>
noobsy: let prob = probOfSents (bigramProbByLength modelLength) test * weight
23:16
<dmwit>
`test :: [String]`, not `(String, String)`, no?
23:16
<dmwit>
Oh, I misread your proposal. Ignore me.
23:25
psychicist__ joined
23:25
<Profpatsch>
johnw: I’ve got a small intermediate datatype where I want to keep a few nix strings.
23:26
<Profpatsch>
data Foo r = Foo { s1 :: NString r, s2 :: NString r }
23:26
<Profpatsch>
But I’m not sure how to use that.
23:27
<Profpatsch>
I can’t do type FooString = Fix NString I think.
23:27
<Profpatsch>
Because the Fix would exclude all other NExpr types then.
23:28
<Profpatsch>
But now I get Couldn't match type NExprF r with Fix NExprF
23:29
<Profpatsch>
Because the NString is not from the fixpoint while the NExpr is.
23:30
<Profpatsch>
Or more accurately: Couldn't match type NString r with Fix NExprF
23:30
<Profpatsch>
"goPackagePath" $= pkgPath goPkg
23:30
psychici1t__ joined
23:34
<Profpatsch>
No idea how to work around that apart from just making all fields in my Foo type of type NExpr
23:37
<ghostprince>
Any IT channels?
23:39
curious_corn joined
23:44
<monochrom>
Oh God, Cabal is moving forward to version 2.x
23:45
<Tuplanolla>
Are you saying they're breaking everything, monochrom?
23:45
<monochrom>
I don't know. I haven't tried.
23:45
<ezyang>
there are a number of breakages
23:45
<monochrom>
But I think I will like "Since version 2.0, the macro CURRENT_PACKAGE_VERSION expands to the string version number of the current package." :)
23:47
<monochrom>
(Also, not on hackage, only on github.)
23:50
<johnw>
Profpatsch: that's an intriguing question, do you have sample code I can play with?
23:52
<johnw>
Profpatsch: I wonder if you need something like data Foo = Foo { s1 :: forall r. NString r, etc ..., so that when you produce a Foo, it can only happen in a general context, allow for any future interpretation
23:54
JeanCarloMachado joined