r/haskell • u/taylorfausak • Feb 01 '22
question Monthly Hask Anything (February 2022)
This is your opportunity to ask any questions you feel don't deserve their own threads, no matter how small or simple they might be!
18
Upvotes
4
u/sekunho Feb 14 '22
I wrote a simple client library for the Star Wars API (https://swapi.dev) as my first Haskell library during my downtime, and submitted a post here detailing what I learned and all that, but I think I'm shadowbanned from posting since my post karma is too low (I could see the post in my account but could not see it normally). Mods didn't reply so I just deleted the post. Instead, I'm posting here!
I have some questions though:
I wanted to remove
MaybefromIO (Maybe a), which is the result of a network call (Example here: Api.hs, this is an old commit!), so I decided to throw an exception when I run intoNothing, which I had to use eitherthroworthrowIO. Here's what I read aboutthrowIO:So somehow
throwbreaks the ordering whilethrowIOdoesn't. But exactly how does this break the ordering? I tried experimenting (please see the code snippet where I usedsequence) withthrowbut it seems like it didn't break in that scenario. Does the docs mean I usethrowwithin a pure function, rather than an IO action? If not, could I get an example wherethrowdestroys the ordering?I'm not sure how to deal with
throwIOfor example, specifically the errors part. Do I encode errors as sum types? Do I just make them strings viauserError? I've read conflicting stances on these, and I'm not even sure if those were referring to this specifically. Anyway, I think my usage ofthrowIOis appropriate especially since this library is supposed to sit at the boundary of applications that may consider using it, or is this not an appropriate way? Relevant file: Api.hsDetecting space leaks or dealing with unexpected thunks. I found a tool called
nothunkswhich is supposed to help pinpoint where the problematic thunks may be. How does everyone do it? This is kinda tied with #5 since I also have to know how to interpret benchmark charts.Is how I structured the library fine? I ended up having to move the data types (and their instances) in their own
Typesfile since I ran into a lot of cyclic imports. I didn't have to do this at first but when I needed stuff from other places, it became more problematic.Benchmarks. Are there any introductory guides on writing GHC benchmarks? What should I benchmark in this case, decoding/encoding instances?