Search Haskell Channel Logs

Wednesday, March 1, 2017

#haskell channel featuring lyxia, kubunto, fbergmann, Rembane, dramforever, Cale, and 10 others.

dramforever 2017-03-01 03:45:08
damn
dramforever 2017-03-01 03:45:31
I'm losing my Haskell skills faster than I can imagine
MarcelineVQ 2017-03-01 03:45:54
there's an option more straight-forward than intercalate as well
MarcelineVQ 2017-03-01 03:46:37
assuming you're working on kubunto's problem :>
dramforever 2017-03-01 03:46:40
Yeah I guess
kubunto 2017-03-01 03:46:45
Detrumi: i am getting a new error now from compilation
robertkennedy 2017-03-01 03:46:54
:t typeRep
lambdabot 2017-03-01 03:46:57
forall k (proxy :: k -> *) (a :: k). Typeable a => proxy a -> TypeRep
dramforever 2017-03-01 03:47:04
no space after 'show a', space before every 'subnode'
robertkennedy 2017-03-01 03:47:43
> typeRep (Just showFFloat)
lambdabot 2017-03-01 03:47:55
Maybe Int -> Double -> [Char] -> [Char]
kubunto 2017-03-01 03:48:09
doesnt like dealing with g as an argument to a sentence: http://lpaste.net/353097
robertkennedy 2017-03-01 03:53:55
Is 'Left the same as `data HLeft` at the type level (with DataKinds)
robertkennedy 2017-03-01 03:54:31
I mean in the case where I have defined and used HLeft, can I refactor to use 'Left?
kubunto 2017-03-01 04:07:01
quite wierd
kubunto 2017-03-01 04:09:24
can anyone explain why i am getting an ambiguous type error in one case but when i run it standalone in ghci it works just fine?
Tuplanolla 2017-03-01 04:09:59
The monomorphism restriction is probably at it again, kubunto.
kubunto 2017-03-01 04:10:20
Tuplanolla: the whositwhatnow?
mauke 2017-03-01 04:10:26
@where dmr
lambdabot 2017-03-01 04:10:26
http://www.haskell.org/haskellwiki/Monomorphism_restriction
Tuplanolla 2017-03-01 04:10:31
Start your file with `{-# LANGUAGE NoMonomorphismRestriction #-}` and see if it helps, kubunto.
Tuplanolla 2017-03-01 04:10:43
If it does, read more about it there.
merijn 2017-03-01 04:10:44
No, don't do that >.<
merijn 2017-03-01 04:11:00
Disabling monomorphismrestriction is a dumb "default" reaction
merijn 2017-03-01 04:11:18
But reading that wiki page is a good idea
Tuplanolla 2017-03-01 04:11:23
Why? I always turn it off.
merijn 2017-03-01 04:11:46
Tuplanolla: What do you prefer? Compile time warnings or hard to debug silent performance degradation?
Tuplanolla 2017-03-01 04:12:01
I've never seen such a problem.
merijn 2017-03-01 04:12:10
Tuplanolla: Because if your answer is "the former", then disabling monomorphism restriction is changing your default to the latter
Tuplanolla 2017-03-01 04:13:00
All of the counterexamples I've seen have been silly.
merijn 2017-03-01 04:14:04
It's always silly counterexamples, until one day it isn't
Tuplanolla 2017-03-01 04:14:36
I'll worry about the extension when it happens then.
merijn 2017-03-01 04:14:54
And then you waste two hours or more debugging an issue that wouldn't have happened if you didn't disable it. Especially since there's a trivial way to get rid of monomorphism issues without disabling it
Tuplanolla 2017-03-01 04:15:01
It's more common that there's a missing `!` somewhere.
danielsmw 2017-03-01 04:15:07
Is there a clear theoretical reason why you might expect performance degredation? I don't know much about what the monomorphism restriction is really giving you.
merijn 2017-03-01 04:16:14
danielsmw: Right, so let's say we have "foo = map expensiveComputation [0..]"
merijn 2017-03-01 04:16:36
danielsmw: Normally if you have an expensive top level computation you'd only expect it to be computed once, right?
danielsmw 2017-03-01 04:16:46
Sure.
kubunto 2017-03-01 04:17:06
merijn: if i understand it correctly, the moment i make a data structure of type graph string int, that the next time i create a new graph of string ? it will be annoyed
merijn 2017-03-01 04:17:35
Since you're just lazily building the result. But if we have a typeclass polymorphic result, like "foo :: Num a => [a]" we have a bit of a problem
kubunto 2017-03-01 04:18:06
merijn: graph is defined as Graph o p
merijn 2017-03-01 04:18:20
danielsmw: Now, what happens if I first use "foo" as "[Double]" and later as "[Int]", both are legal, based on "Num a => [a]", yes?
danielsmw 2017-03-01 04:18:37
merijn: those are both legal, yes
Tuplanolla 2017-03-01 04:18:44
I don't see this as a problem, merijn. If you request two results with different types, you can expect two different computations.
merijn 2017-03-01 04:18:49
danielsmw: Now, clearly I have to compute it once in each case
merijn 2017-03-01 04:18:55
Tuplanolla: It's worse than that!
danielsmw 2017-03-01 04:18:56
merijn: sure
lyxia 2017-03-01 04:19:27
Tuplanolla: but if you require it twice with the same type it's not clear that it will be run only once.
dramforever 2017-03-01 04:19:29
Tuplanolla: Even if I request twice with the same type, it's going to recompute
merijn 2017-03-01 04:19:31
In other words, GHC can't really memoise the result, since it doesn't know which different types you are going to use
Tuplanolla 2017-03-01 04:19:40
I see.
merijn 2017-03-01 04:19:47
So even if you use it as [Int] 10 times, you recompute it all of those times
merijn 2017-03-01 04:20:22
The only other solution is to store one copy of foo per type, but if you only use it once for 10 different types that ends up wasting a ton of memory for no reason
Tuplanolla 2017-03-01 04:20:27
That's a bit annoying, but I'm not bothered.
danielsmw 2017-03-01 04:20:43
merijn: does the specialize pragma relieve this issue for particular types?
merijn 2017-03-01 04:20:49
For functions that's usually not an issue, but for values it's kinda annoying
danielsmw 2017-03-01 04:20:56
ah
merijn 2017-03-01 04:21:15
The logic being, if it's a non-function you're probably expecting it to be memoized
dramforever 2017-03-01 04:21:15
I used to do NoMonomorphismRestriction. But then I learned to write all top-level signatures, and I've never found myself needing that again
kubunto 2017-03-01 04:21:38
dramforever: toplevel sigs?
merijn 2017-03-01 04:21:49
danielsmw: So the solution chosen in the report is to say that any top-level polymorphic non-function gets monomorphised
Rembane 2017-03-01 04:21:52
I used to be a NoMonomorphismRestriction like you, but then I took a top-level signature to the knee.
Tuplanolla 2017-03-01 04:22:00
If it ever does become a problem, I'll just turn the extension off when the module is finished.
merijn 2017-03-01 04:22:43
danielsmw: So if I have "foo :: Num a => [a]" and GHC sees you use it as '[Int]' GHC simply goes 'welp...I'm just gonna assume this is *always* Int so I can have the memoised behaviour you expect of things that are not typeclass polymorphic"
dramforever 2017-03-01 04:23:25
kubunto: I don't think this will solve your problem in that code
merijn 2017-03-01 04:23:33
danielsmw: The result is: If you have a top level non-function that you only use with 1 type it "Just Works" (efficiently!). If you use it with 2 different types you get a compile error (easy to detect!)
kubunto 2017-03-01 04:23:52
dramforever: i know why the problem is there
kubunto 2017-03-01 04:24:03
cant figure out the second generic type
merijn 2017-03-01 04:24:09
danielsmw: The other solution would be, to assume it's polymorphic and always recompute. But if you're not thinking of that you get expensive recomputation at runtime (tricky to detect!)
merijn 2017-03-01 04:24:37
danielsmw: And when writing the standard "loud compile errors" were deemed preferable to silent bad performance
merijn 2017-03-01 04:25:22
danielsmw: Of course, it's trivial to get rid of the error if you DO want it to be polymorphic, which is: write an explicit type signature. GHC only monomorphises top-level, non-function values without a type
hexagoxel 2017-03-01 04:25:32
Tuplanolla: i'll paraphrase my case: In some part of a synthesizer i needed silence as a default case. So i had a local let zeroVec = SV.sample 96000 (const 0.0). Due to NMMR, this had some non-monomorphic type (Fractional t => SV.Vector t), and it created a new vector for each use of that binding, even though it only ever needed Vector Floats.
merijn 2017-03-01 04:25:38
danielsmw: But that way you're at least forced to conciously decide "this should be recomputed all the time"
kubunto 2017-03-01 04:26:08
dramforever: my initial issue was because the compiler couldnt figure out what hte second type was for Graph op when all it had to go on was Node String
kubunto 2017-03-01 04:26:24
graph o p*
dramforever 2017-03-01 04:26:39
Oh there's a second issue?
kubunto 2017-03-01 04:27:01
dramforever: nah, that is just what started this
danielsmw 2017-03-01 04:28:39
merijn: I see.
danielsmw 2017-03-01 04:29:15
merijn: So actually, I've /always/ written top level sigs, and the only time GHC has suggested NMRestriction to me is when I've used certain external libraries.
dramforever 2017-03-01 04:29:28
Wait a sec
danielsmw 2017-03-01 04:29:32
But you're saying that when I have top level polymorphic functions, they're not going to be memoized?
dramforever 2017-03-01 04:29:37
That's not because of MonomorphismRestriction right?
dramforever 2017-03-01 04:29:43
That's ExtendedDefaultRules
Tuplanolla 2017-03-01 04:30:22
It helps to mentally treat `=>` like `->` when reasoning about performance.
dramforever 2017-03-01 04:30:31
If you start ghci with -Wall it tells you it defaulted the type of g to Graph String ()
merijn 2017-03-01 04:30:47
danielsmw: memoised isn't really the right term, but anyway. For functions it's not really relevant, since everytime you pass in a new argument you have to compute the result from scratch anyway
merijn 2017-03-01 04:31:25
danielsmw: If you always write top level sigs the ambiguity where NMR kicks in is never there, because you're always explicitly telling GHC what you're expecting
dramforever 2017-03-01 04:31:36
wait a sec...
danielsmw 2017-03-01 04:31:58
merijn: Ah, okay, sure. So it really only does matter if I have constant valued top level computations, which I want to be polymorphic. Which does sort of seem edge-casey, but I can imagine it happening.
danielsmw 2017-03-01 04:32:07
(in practice)
dramforever 2017-03-01 04:32:16
Enabling NoMonomorphismRestriction *does not* solve kubunto's problem
dramforever 2017-03-01 04:32:23
ExtendedDefaultRules *does*
merijn 2017-03-01 04:32:53
danielsmw: Well, if you generate, e.g., a top-level vector of 10,000 entries, you'd probably want it to only be computed once :)
danielsmw 2017-03-01 04:33:07
merijn: Indeed :) thanks!
merijn 2017-03-01 04:33:40
danielsmw: And it doesn't happen a lot, sure. It's just that *when* it does it probably results in hair pulling debugging if you let it happen silently :p
Cale 2017-03-01 04:34:32
If apparent constants are *type class* polymorphic, then they won't be memoised, because they're secretly functions (of the type class dictionary), and the results of functions are never retained on their own (to do so automatically would basically mean giving up on garbage collecting anything ever)
kubunto 2017-03-01 04:34:34
merijn: this extended defaults thing looks right
kubunto 2017-03-01 04:34:54
dramforever: is that ignored in standard ghci?
dramforever 2017-03-01 04:36:41
It's turned on by default in GHCi
dramforever 2017-03-01 04:36:52
You can :set -XNoExtendedDefaultRules
dramforever 2017-03-01 04:37:08
Quick check: 'print []' changes from 'works' to 'doesn't work'
kubunto 2017-03-01 04:37:52
how would i specify a type for the generics in my definition?
kubunto 2017-03-01 04:38:10
data Num d => Graph d o = Leaf d | Node o [Graph d o] deriving (Show)
kubunto 2017-03-01 04:38:24
ignoring the num d part
dramforever 2017-03-01 04:38:43
kubunto: You don't
dramforever 2017-03-01 04:38:50
because you don't need to
delYsid 2017-03-01 04:39:14
How do I write a parser combinator that works like many, but only counts occurances?
Tuplanolla 2017-03-01 04:39:37
You `fmap length`, delYsid?
delYsid 2017-03-01 04:39:42
the efficient version of length <$> many p
dramforever 2017-03-01 04:40:04
kubunto: You want to use -Wall
delYsid 2017-03-01 04:40:21
Tuplanolla: Yeah, thats the obvious version, but I'd like to avoid the consing.
kubunto 2017-03-01 04:40:28
dramforever: as long as ther is a leaf in the graph, it is good
lyxia 2017-03-01 04:40:32
delYsid: take the definition of many and inline length <$> into it
kubunto 2017-03-01 04:40:52
no leaf -> no compilation
dramforever 2017-03-01 04:40:58
As you can see GHC defaults your types beyond what you would like
dramforever 2017-03-01 04:41:25
This is a hint: add more signatures
lyxia 2017-03-01 04:41:55
delYsid: aren't you optimizing prematurely
delYsid 2017-03-01 04:42:18
lyxia: no :-)
kubunto 2017-03-01 04:42:19
dramforever: how would i specify in place of the generics in my definition
dramforever 2017-03-01 04:42:27
specify what?
kubunto 2017-03-01 04:42:33
int and char
kubunto 2017-03-01 04:42:41
int and char
kubunto 2017-03-01 04:42:43
or rather [char]
dramforever 2017-03-01 04:43:06
That's not 'generics' any more
fbergmann 2017-03-01 04:43:27
q
jnj 2017-03-01 04:43:34
Is something like this possible: class X a where { someThing :: a -> b } (so a type class with a single function someThing returns an unknown type 'b')
kubunto 2017-03-01 04:43:35
dramforever: i know
kubunto 2017-03-01 04:44:00
i want to know how to make it non generic
dramforever 2017-03-01 04:44:06
You want to specify the types of a through g?
dramforever 2017-03-01 04:44:28
a :: Graph Int String
Cale 2017-03-01 04:44:51
jnj: That would mean that someThing would produce a value of any result you wanted it to, which pretty much means that it has to fail.