Search Haskell Channel Logs

Wednesday, March 1, 2017

#haskell channel featuring kmelva, flxw, user1872, johnw, dolio, robkennedy, and 31 others.

Tuplanolla 2017-03-01 06:56:40
Does `ResourceT` release in the reverse allocation order or some random order?
Tuplanolla 2017-03-01 06:57:13
It's not mentioned in the documentation.
johnw 2017-03-01 06:57:14
Tuplanolla: given that they could be inter-dependent, reverse is the only thing that makes sense to me
Arguggi 2017-03-01 06:58:35
I read https://tech.channable.com/posts/2017-02-24-how-we-secretly-introduced-haskell-and-got-away-with-it.html and I don't understand why "we cannot run runWorkerLoop and runFetchLoop with forkIO, because we don't have the right transformer stack.". Why won't liftIO work?
Forkk 2017-03-01 06:59:08
Is it possible to run valgrind on C code called from Haskell?
johnw 2017-03-01 06:59:10
forkIO *wants* an IO action
johnw 2017-03-01 06:59:19
they could do it with monad-control
Forkk 2017-03-01 06:59:38
It seems to fail setting up function redirection
johnw 2017-03-01 06:59:52
which one can do easily by using lifted-async
Unhammer 2017-03-01 06:59:52
https://www.haskell.org/hoogle/?hoogle=forkliftio
Unhammer 2017-03-01 06:59:57
missed opportunity there
sternmull 2017-03-01 07:00:29
is there a trick to see the precedence inside expressions? When i look at complex expressions i often struggle to see what ends up in which operator/function. It would be helpful to visualize the syntax tree in some way.
Arguggi 2017-03-01 07:01:26
johnw, aaaaaah I think I understand now
ertes 2017-03-01 07:02:06
sternmull: you can ask GHCi about the precedence of individual operators via :i
ertes 2017-03-01 07:02:12
like: :i (+)
monochrom 2017-03-01 07:03:01
Arguggi: You may be thinking "liftIO (forkIO xxx)" but the issue is "forkIO runWorkerLoop"
sternmull 2017-03-01 07:03:01
ertes: Yes i know... but sometimes it would be nice if it could insert brackets into an expression or something like that.
Cale 2017-03-01 07:03:29
sternmull: The most important thing to remember about precedence (and which isn't strictly speaking a precedence rule) is that function application always binds more tightly than any infix operator
Cale 2017-03-01 07:04:24
So, regardless of the precedence of *, f x y * g z will always be (f x y) * (g z)
sternmull 2017-03-01 07:04:59
at the moment i am looking at something like "(a b . c d) e" and wonder what to think of it.
mauke 2017-03-01 07:05:17
((a b) . (c d)) e
Cale 2017-03-01 07:05:31
That's the same as a b (c d e)
sternmull 2017-03-01 07:06:26
ok, thanks. But at that point i wondered what i will do when i encounter more exotic operators. After all they can be all get their custom precedence...
Cale 2017-03-01 07:06:28
So a b and c d are functions, they're being composed and then the composite is being applied to e
Arguggi 2017-03-01 07:06:33
monochrom yes I didn't think of that for some reason. You can "run" the action returning it to IO a and then fork that action right? (which seems to be what was suggesting in the comments unlift :: m r -> m (IO r) )
Cale 2017-03-01 07:07:10
sternmull: Somehow I practically never find myself needing to care about the actual precedence level of operators in Haskell
davean 2017-03-01 07:07:31
I only care when reading edwardk's code
Cale 2017-03-01 07:07:50
Yeah, it's possible to go overboard
monochrom 2017-03-01 07:07:51
Yes, but this means the new thread has nothing to do with the parent thread in terms of what the transformer stack wants to carry, usually.
flxw 2017-03-01 07:08:03
Hi all. Applicative on a tupple lets me do (x,f) <*> (y,a) ==> (x <> y, f a), in case x,y are from the same Monoid. I'm for awhile trying to get <*> working with Semigroup Last on the first component of the pair. Is that not possible? I mean, memtpy should not be needed for this, no?
sternmull 2017-03-01 07:08:17
Cale: Ok. This is more like a diffuse fear. I haven't written/read enough haskell to know if this is a problem in practice.
Cale 2017-03-01 07:08:18
But for the most part, things will be obvious from the types, in cases where the precedence matters at all
sternmull 2017-03-01 07:09:02
yes, type checks will probably catch many accidents.
monochrom 2017-03-01 07:09:56
Basic example: If you use StateT Int IO, you can pretend you have a mutable variable. But once you start doing liftIO (forkIO (runStateT ...)), the new thread's "mutable variable" is now divorced from the parent thread's.
mauke 2017-03-01 07:10:24
they're not even on speaking terms
monochrom 2017-03-01 07:10:25
And even monad-control will not change this.
ystael 2017-03-01 07:10:30
Cale: honestly I think it would be a perfectly reasonable design to say "application has precedence +inf, $ has precedence -inf, everything else *must* be parenthesized" :)
Arguggi 2017-03-01 07:10:36
monochrom, ok thanks that clears everything up
mauke 2017-03-01 07:11:11
record update has precedence inf + 1
kuribas 2017-03-01 07:11:16
> (a b . c d) e
lambdabot 2017-03-01 07:11:19
error:
lambdabot 2017-03-01 07:11:19
• Couldn't match expected type 'Expr -> b0 -> c'
lambdabot 2017-03-01 07:11:19
with actual type 'Expr'
mauke 2017-03-01 07:12:06
> let [a,b,c,d] = map fun ["a","b","c","d"] in (a b . c d) e
lambdabot 2017-03-01 07:12:11
error:
lambdabot 2017-03-01 07:12:11
• Could not deduce (Show b0) arising from a use of 'a'
lambdabot 2017-03-01 07:12:12
from the context: FromExpr c
mauke 2017-03-01 07:13:11
oh, I'm dumb
byorgey 2017-03-01 07:14:37
flxw: mempty is not needed for <*>, but it is needed for pure.
mauke 2017-03-01 07:14:40
> let [a,c :: Expr->Expr->Expr] = map fun ["a","c"] in (a b . c d) e
lambdabot 2017-03-01 07:14:45
a b (c d e)
catern 2017-03-01 07:15:08
hey #haskell, I've constructed a type (say, a Passenger) which only makes sense/is meaningful in the context of another type (say, a Vehicle). how should I express this in types? should I add a list of passengers to vehicle, add a reference to vehicle into passengers, or do something else entirely??
kuribas 2017-03-01 07:15:37
> (f x . g y) z :: Expr
byorgey 2017-03-01 07:15:37
flxw: you may be interested in http://hackage.haskell.org/package/semigroupoids-5.1/docs/Data-Functor-Apply.html
lambdabot 2017-03-01 07:15:42
error:
lambdabot 2017-03-01 07:15:42
• Ambiguous type variable 'b0' arising from a use of 'f'
lambdabot 2017-03-01 07:15:42
prevents the constraint '(Show b0)' from being solved.
Cale 2017-03-01 07:15:42
catern: One of the above?
catern 2017-03-01 07:15:55
Cale: but which one :(
flxw 2017-03-01 07:16:19
byorgey: Oh, thank you. Yes, pure needs mempty, because it must produce a value of type a out of thin air.
byorgey 2017-03-01 07:16:30
flxw: right
Cale 2017-03-01 07:16:42
catern: That really depends on what your program does
catern 2017-03-01 07:17:08
but I want easy answers :(
mauke 2017-03-01 07:18:10
ask easy questions
Cale 2017-03-01 07:18:20
catern: Depending on the circumstances, you might also have some sort of identifiers or references to passengers or vehicles, and you'd be using those in the fields instead.
catern 2017-03-01 07:18:47
Cale: right! that's yet another alternative!
kuribas 2017-03-01 07:19:13
> (f x . (g y :: Expr -> Expr)) (z::Expr) :: Expr
Cale 2017-03-01 07:19:16
Also, instead of a list of passengers, it's quite possible that a Set is more appropriate
lambdabot 2017-03-01 07:19:17
f x (g y z)
Cale 2017-03-01 07:19:38
Or you might have a Map Vehicle (Set Passenger)
catern 2017-03-01 07:19:42
Cale: sure sure yeah that's not directly related though
catern 2017-03-01 07:19:56
(set vs list I mean)
Cale 2017-03-01 07:20:20
Well, it makes a difference, but maybe not the difference you're concerned about :)
catern 2017-03-01 07:20:32
indeed :)
Cale 2017-03-01 07:20:44
Or a Map Passenger Vehicle
Cale 2017-03-01 07:20:56
Or a Map Passenger VehicleId
Cale 2017-03-01 07:20:59
heheh
catern 2017-03-01 07:21:26
I think VehicleId would be strictly worse
catern 2017-03-01 07:21:38
at least from an abstract programming language point of view
catern 2017-03-01 07:21:54
a VehicleId is only meaningful given a Map VehicleId Vehicle
Cale 2017-03-01 07:21:54
Well, think about the case that Vehicle simply describes the characteristics of the vehicle, but doesn't identify it uniquely
Cale 2017-03-01 07:22:23
In that case, having a Map Passenger Vehicle doesn't allow you to determine that two people are in the same car
Cale 2017-03-01 07:22:29
Just that they're in the same sort of car
Sonolin 2017-03-01 07:22:41
well Vehicle could have an "id" field in that case, right?
Cale 2017-03-01 07:22:47
It could
catern 2017-03-01 07:22:49
oh, sure, sure, but I think it's definitely better to have an id field in Vehicle
Cale 2017-03-01 07:22:54
(probably you wouldn't call it id)
Cale 2017-03-01 07:23:00
;)
Sonolin 2017-03-01 07:23:01
lol, yea
Sonolin 2017-03-01 07:23:11
silly non-haskell brain
mbrock 2017-03-01 07:23:17
naming types after real world object types is often confusing, in functional programming as well as object oriented programming...
mbrock 2017-03-01 07:23:38
there are no vehicles inside your computer!
catern 2017-03-01 07:23:58
a good point
byorgey 2017-03-01 07:24:07
on the other hand, naming everything VehicleInformationEncoding is kind of confusing too =P
Cale 2017-03-01 07:24:09
It's best to have some idea what you're going to be doing with the data as you plan out the structures you're going to store it in
catern 2017-03-01 07:24:10
but, I'm not actually talking about vehicles and passengers, but rather something that exists only in my computer :)
catern 2017-03-01 07:24:39
(Vehicles and Passengers in a game, say)
catern 2017-03-01 07:26:27
Cale: I mean, I find myself frequently encountering the situation where I have a type (like Passenger or VehicleLookupKey) where the values are only meaningful when considered in a context which contains a value of another type (like Vehicle or Map VehicleLookupKey Vehicle)
catern 2017-03-01 07:26:54
so I would like it to be true that there was some general purpose way to think about these cases :)
catern 2017-03-01 07:27:05
some type theory construct?
dminuoso 2017-03-01 07:28:19
Do you folks handwrite your actions creators and reducers for REST interaction? A single endpoint produced so much ugly boilerplate...
dminuoso 2017-03-01 07:28:27
Oh boy. Wrong channel. :|
Younder 2017-03-01 07:29:24
For what it's worth there is no toxonometry that works for every case. This was proved by Wittgenstein. The best you can do is use a user case, a universe of discource, to model the data.
ertes 2017-03-01 07:31:32
catern: i find myself using an approach like this from time to time, depending on the application: data Vehicle passenger = Vehicle { …, _passenders :: [passenger], … }
ertes 2017-03-01 07:32:22
when it's fresh out of the database, i have a (Vehicle (Key Passenger)), which i can 'traverse' into a (Vehicle Passenger) if necessary
NemesisD 2017-03-01 07:35:12
hi all. i remember there being an extension or feature in recent GHC that lifted constructors to the type level (canonical example of Nat). is there a similar thing for sum types, i.e. data X = A | B, lifting A and B into the type system as distinct types?
NemesisD 2017-03-01 07:36:01
i've got something like data ClearanceLevel = TopSecret | MailRoom and am trying to create a type-level annotation like MinimumClearance TopSecret
catern 2017-03-01 07:36:08
ertes: interesting notion, I kind of like that
NemesisD 2017-03-01 07:36:25
so i'd want to reflect the constructor on the type level to the constructor in the value level
catern 2017-03-01 07:37:15
ertes: I guess you would reverse this to have data Passenger vehicle, and (Passenger (Key Vehicle)) (Passenger Vehicle)
catern 2017-03-01 07:37:40
would/could
catern 2017-03-01 07:37:53
and then passenger would be meaningful on its own...
NemesisD 2017-03-01 07:38:04
i guess i'm looking for DataKinds
ertes 2017-03-01 07:38:36
NemesisD: you might also be interested in the latest goodie: -XTypeInType
ertes 2017-03-01 07:39:06
it completely collapses all levels above values into a single type level
ertes 2017-03-01 07:40:53
however, communication between value and type level is still manual and ad-hoc
catern 2017-03-01 07:41:13
it's okay, I suppose, to always pass Passengers around with also Vehicles. the thing that I want to prevent, I guess, is partnering a Passenger with the wrong Vehicle... I suppose I could just make a PassengerVehicle type
ertes 2017-03-01 07:41:31
there are two major approaches: reflection (a.k.a. implicit configurations) and singletons
ertes 2017-03-01 07:41:46
you probably need the latter, because the former does not support type-level functions
flxw 2017-03-01 07:41:58
byorgey: thank you for the semigroupoids url. After pondering about the types for a while, I learnt that <.> does the trick. :)
NemesisD 2017-03-01 07:46:20
ertes: so i've got data Clearance = TopSecret | None, data MinClearance (clearance :: Clearance) , is it actually possible to write reflectMinClearance :: MinClearance clearance -> Clearance ?
kmelva 2017-03-01 07:47:40
is ZuriHac free to attend?
kmelva 2017-03-01 07:47:51
looking at the site there's no mention of admission price...
johnw 2017-03-01 07:48:48
kmelva: I'm pretty sure it's a hackathon, open to all, rather than an admissions-based conference
flxw 2017-03-01 07:48:58
when a functor description says "lax monoidal functor", the lax is concerned with the monoid part, and saying that the monoid laws are not valid upto equality, but just upto natural isomorphisms. Do I get this right?
johnw 2017-03-01 07:49:00
(for example, Compose)
kmelva 2017-03-01 07:49:42
johnw: ah cool, I just figured it was a regular conference where you have to pay for admission... never thought about going because I figured it would be too expensive :/
johnw 2017-03-01 07:49:55
flxw: https://en.wikipedia.org/wiki/Monoidal_functor
dolio 2017-03-01 07:50:02
flxw: Sort of. But there's no "monoid" exactly.
flxw 2017-03-01 07:50:19
because it is a tensor product?
dolio 2017-03-01 07:50:37
It's about 'preservation' of monoidal category structure being directional.
dolio 2017-03-01 07:50:46
And not up to equality.
dolio 2017-03-01 07:51:16
And not even up to isomorphism, actually.
flxw 2017-03-01 07:51:16
okay, I'll read the hinted at url.
flxw 2017-03-01 07:51:25
I see. :)
dolio 2017-03-01 07:53:22
In general, I think 'lax' is used when you replace isomorphisms with transformations in one direction.
dolio 2017-03-01 07:53:45
And there's also 'oplax' sometimes for things that replace isomorphisms with transformations in the opposite direction.
Younder 2017-03-01 07:59:15
an isomorpism is by nature in both directions
Younder 2017-03-01 07:59:46
You might also call it a bijective transform
Younder 2017-03-01 08:00:24
or on to one and onto. The three are equivalent
Younder 2017-03-01 08:02:27
simulary you have a monmorphic transform which could also be called a projection
Younder 2017-03-01 08:04:21
Perhaps 'Introduction to Lattices and Order' by Davey and Priestley can help
Tuplanolla 2017-03-01 08:05:30
Help whom, Younder?
Younder 2017-03-01 08:07:55
Well when I was first introduced to Haskell I was overwhelmed by number of mathematical terms. So I found that my education lacked a few pointers. That book helped me understand the terminology and the frame of mind of a Haskeller better
ertes 2017-03-01 08:20:46
NemesisD: what should that function do?
NemesisD 2017-03-01 08:21:31
ertes: i found a workable solution, i wanted reflect from the reflection package and i just need to write reifies instances for the constructors i care about
ertes 2017-03-01 08:28:34
NemesisD: if you need to write Reifies instances by hand, you probably should just use singletons in the first place
NemesisD 2017-03-01 08:29:09
ertes: yeah its a matter of boilerplate vs transparency imo
NemesisD 2017-03-01 08:29:29
i reckon if i've only got a few constructors to deal with its fine for me to hand write the reifies instances
ertes 2017-03-01 08:38:49
NemesisD: the idea is that you shouldn't write Reifies instances except in certain cases, which are basically use cases of singletons
NemesisD 2017-03-01 08:39:42
ertes: what is the problem i'm creating here and avoiding with singletons TH? that i could screw up one of my 3 instances of Reifies or is it something else?
johnw 2017-03-01 08:48:40
NemesisD: you could also reify a Prism
Younder 2017-03-01 08:49:22
Tuplanolla, For the record what i said about monomorpism is completely wrong its is a transorm from a space A onto A. Not a projection.
Younder 2017-03-01 08:50:47
Tuplanolla, Unfortunately it is now on record forever.
NemesisD 2017-03-01 08:51:04
johnw: interesting, i'm not sure if you could contain this in a prism though since MinClearance TopSecret and MinClearance None are different types
mnoonan 2017-03-01 09:03:38
has anybody used the LibClang package before? when I try to use it in a project, I'm getting a ton of link errors of the form "undefined reference to `__c2hs_wrapped__clang_XXX`" and I'm not quite sure how to debug further.
flxw 2017-03-01 09:04:59
dolio: Hmm, a question on terminology. I've grepped four texts on category theory for "lax" (Awodey, Wells, Pierce, Riehl) now, and had not a single hit. Is it, because lax monoidal categories are a more advanced concept, or that different groups call it differently?
mnoonan 2017-03-01 09:06:55
flwx: it's a notion from higher category theory, so I wouldn't be shocked if it was omitted from intro texts
flxw 2017-03-01 09:08:59
mnoonan: aha, I see. okay, then it's not for me for the time being ...
flxw 2017-03-01 09:10:11
(just for completeness sake: yes, the searched books are all on basic category theory)
dmwit 2017-03-01 09:14:40
flxw: You might like to look it up in ncatlab.
dmwit 2017-03-01 09:15:31
https://www.google.com/search?q=lax%20site%3Ancatlab.org has a few hits that look relevant
dmwit 2017-03-01 09:16:39
(Though beware that ncatlab does not try very hard to cater to beginners.)
Tuplanolla 2017-03-01 09:18:56
I can't figure out how to write the `bracket2` analogue (http://lpaste.net/352987) of `allocate` (https://hackage.haskell.org/package/resourcet/docs/Control-Monad-Trans-Resource.html).
Tuplanolla 2017-03-01 09:19:27
It seems that `Control.Monad.Trans.Resource.Internal` doesn't expose all the internal things.
flxw 2017-03-01 09:20:04
dmwit: thanks alot for the pointers. beginner friendly: yeah, I am seeing this just now. :)
Tuplanolla 2017-03-01 09:25:58
Maybe I don't need to...
flxw 2017-03-01 09:34:49
fmap acts on the second component of a pair. Is there a instance of fmap for (,) which acts on the first one? (Right now I'm doing swap twice)
Tuplanolla 2017-03-01 09:35:38
Well, `bimap f id`, but...
opqdonut 2017-03-01 09:35:50
flxw: it can't, because functor is parameterized on the last type variable
robkennedy 2017-03-01 09:36:05
There are things called Bifunctors which have that property. Overloading instances are not generally good
kuribas 2017-03-01 09:36:25
is it possible to break in ghci when a condition is met?
opqdonut 2017-03-01 09:36:45
I'd use a lens, or Control.Arrow.first
Forkk 2017-03-01 09:36:55
Maybe I'm being stupid here, because I feel like this should be obvious, but I can't figure out how to get a Ptr from a ForeignPtr
Forkk 2017-03-01 09:37:00
is there some function to do that or something?
MarcelineVQ 2017-03-01 09:37:04
kuribas: yus https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#the-ghci-debugger
EvanR 2017-03-01 09:37:18
Forkk: right
ski 2017-03-01 09:37:18
@hoogle withForeignPtr
lambdabot 2017-03-01 09:37:18
Foreign.ForeignPtr withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
lambdabot 2017-03-01 09:37:18
Foreign.ForeignPtr.Safe withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
lambdabot 2017-03-01 09:37:18
Foreign.ForeignPtr.Safe.Compat withForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
EvanR 2017-03-01 09:37:28
the dox
Forkk 2017-03-01 09:37:44
that's why I said maybe I'm being stupid :P
Forkk 2017-03-01 09:37:48
because it turns out I was lol
ski 2017-03-01 09:38:06
@type ContT . Foreign.ForeignPtr.withForeignPtr
lambdabot 2017-03-01 09:38:09
GHC.ForeignPtr.ForeignPtr a -> ContT r IO (GHC.Ptr.Ptr a)
kuribas 2017-03-01 09:38:24
MarcelineVQ: sorry, but I don't see how to break on a condition...
Forkk 2017-03-01 09:38:40
I have no idea how I didn't see that function in the docs
flxw 2017-03-01 09:39:00
opqdonut: oh, because the type is partially applied, and the type variables are in order a b, so a is fix in (a,b), yes?
mauke 2017-03-01 09:39:42
flxw: yes
flxw 2017-03-01 09:39:58
cool, again what learnt.
ski 2017-03-01 09:40:22
`(,) a' is an instance of `Functor'
chreekat 2017-03-01 09:40:30
I'm using +RTS -xc to look at some traces, and some of the entries end with a backslash, for instance "Stack.Build.build.\" . What does that mean?
kuribas 2017-03-01 09:40:38
MarcelineVQ: only at a particular line or function.
mauke 2017-03-01 09:40:49
I see your English is one wall free
ski 2017-03-01 09:40:53
one can't write `\a -> (a,b)' as a type to be an instance of `Functor'
chreekat 2017-03-01 09:41:31
Oh, I can answer my own question. It's a lambda.
Zemyla 2017-03-01 09:44:17
Why is Proxy not a MonadFix?
Zemyla 2017-03-01 09:45:12
instance MonadFix Proxy where mfix _ = Proxy
Zemyla 2017-03-01 09:45:17
Seems like the simplest thing in the world.
MarcelineVQ 2017-03-01 09:45:32
kuribas: Ah hmm, you'll need to make the conditon a branch of the code you're examining I guess. I suppose there isn't global state to ask about so conditions only make sense in context
c_wraith 2017-03-01 09:45:48
Zemyla, submit it to the libraries list. (some people will argue about strictness properties, probably)
kuribas 2017-03-01 09:46:26
MarcelineVQ: well, something like "myVar > 20" or so...
kuribas 2017-03-01 09:47:29
MarcelineVQ: I could of course trigger an exception when the condition occurs, then break on the exception...
ski 2017-03-01 09:51:16
> undefined >>= return :: Proxy ()
lambdabot 2017-03-01 09:51:20
Proxy
danilo2_ 2017-03-01 10:14:29
Hi! :) I've got not a very popular use case here, however, I'm wondering if is it possible to re-export in a module constructors but not their types? I've got data Foo = A | B and I want a module to re-export A and B but not Foo
EvanR 2017-03-01 10:14:57
how would people write type signatures...
danilo2_ 2017-03-01 10:15:13
EvanR: By importing the original module
danilo2_ 2017-03-01 10:16:18
EvanR: the datatype is in module M1 and I want M2 to re-export only constructors if its possible.
ski 2017-03-01 10:18:30
did you try only listing the data constructors ?
danilo2_ 2017-03-01 10:21:06
ski: Right, I was somehow mid-closed to reexporting things like module ... (module X) where import M1 (Foo(...)) as X, but right, listening constructors explicitly would do the trick. by the way, im not using it in any prodution code, I was just wondering if ist possible not seeing a simple solution
danilo2_ 2017-03-01 10:21:13
*mind-closed
EvanR 2017-03-01 10:25:24
I don't think parsec can't let you resume in the middle with more input. But can it at least give you the remaining input after a successful parse?
srhb 2017-03-01 10:39:39
EvanR: getInput is a parser that just consumes everything,
srhb 2017-03-01 10:40:30
EvanR: (You could use setInput to continue with something else)
EvanR 2017-03-01 10:41:03
interesting
EvanR 2017-03-01 10:41:26
though would be nicer to have that in the external interface than in the DSL
user1872 2017-03-01 10:44:24
Hey! I've been using haskell for a while, but I've only just heard people throw "strict haskell" around. The only thing I can find on the topic is the strict pragma, but I feel like they're talking about something more than just the pragma
user1872 2017-03-01 10:45:03
do you all know of any good tutorials or descriptions of strict haskell and how to structure your code so that it's not lazy?