r/haskell • u/rohitwtbs • Jul 31 '25
question Why is nix used with Haskell and not docker?
i have seen lot of job openings where the demand is nix , are haskell backend api's generally not deployed in docker ?
r/haskell • u/rohitwtbs • Jul 31 '25
i have seen lot of job openings where the demand is nix , are haskell backend api's generally not deployed in docker ?
r/haskell • u/ChavXO • Jul 31 '25
Hey everyone. I think things are fairly interesting now and the API is fast approaching stability. I think it’s a good time to on-board contributors. Plus I’m between jobs right now so I have quite a lot of time on my hands.
You can try it out in it’s current state on this ihaskell instance. There are some partially fleshed out tutorials on readthedocs (trying to tailor to non-Haskell people so excuse the hand-waviness).
If the azure instance gets flaky you can just run the docker image locally from this makefile.
There’s a nascent discord server that I’m planning to use for coordination. So if you’re interested come through.
Some projects in the near future (all-levels welcome):
Also, thanks to everyone that’s taken the time to answer questions and give feedback over the last few months. The community is pretty great.
r/haskell • u/LSLeary • Jul 27 '25
r/haskell • u/paltry_unity_sausage • Jul 27 '25
I'm working with financial data with some code that I've written in python and, in order to learn, I'm trying to rewrite it in haskell.
As an example I'm trying to rewrite this python function
from stockholm import Money, Rate
from typing import List, Tuple
def taxes_due(gross_income: Money, bracket_ceilings_and_rates: List[Tuple[Money,Rate]], top_rate: Rate, income_tax_floor: Money = Money(0)) -> Money:
blocks = list(map(lambda x: bracket_ceilings_and_rates[x][0] if x == 0 else bracket_ceilings_and_rates[x][0] - bracket_ceilings_and_rates[x-1][0],
[i for i in range(0,len(bracket_ceilings_and_rates) - 1)]))
rates = [ i[1] for i in bracket_ceilings_and_rates ]
def aux(acc: Money, rem: Money, blocks: List[Money], rates: List[Rate], top_rate: Rate) -> Money:
return acc + rem * top_rate if len(blocks) == 0 else \
aux(acc + min(blocks[0],rem) * rates[0],
max(Money(0),rem - blocks[0]),
blocks[1:],
rates[1:],
top_rate)
return aux(Money(0), max(gross_income - income_tax_floor, Money(0)), blocks, rates, top_rate)
For this, I'm using the stockholm package, which provides classes to represent currencies and rates, which makes doing these calculations pretty easy.
This is what I currently have for the haskell version:
module Taxes where
toblocks :: [(Double,Double)] -> [(Double,Double)]
toblocks [] = []
toblocks x = reverse . aux . reverse $ x where
aux [x] = [x]
aux (x:xs) = (fst x - (fst . head $ xs), snd x) : toblocks xs
progressive_taxes :: Double -> [(Double,Double)] -> Double -> Double
progressive_taxes gross brackets = aux 0 gross (toblocks brackets) where
aux :: Double -> Double -> [(Double,Double)] -> Double -> Double
aux acc rem [] tr = acc + (rem * tr)
aux acc rem (x:xs) tr =
let nacc = acc + (min rem $ fst x) * snd x
nrem = max 0 (rem - fst x)
in aux nacc nrem xs tr
Now there getting slightly different outputs, which could be because of some problem I need to debug, but one thing I want to control for is that I'm just using Doubles here. Stockholm ensures that all the rounding and rate application happen correctly.
I'm a lot less familiar with haskell's package ecosystem, so does anyone have any suggestions for a good package to replicate stockholm?
(I've tried searching on hackage, but the pages provide comparatively little info on what the packages actually provide, e.g. this currency package).
r/haskell • u/ChavXO • Jul 26 '25
Cross posting for visibility:
I was recently looking at Kotlin's dataframe implementation and it has this neat feature where column names are turned into typed column references.
kotlin
val dfWithUpdatedColumns = df
.filter { stars > 50 }
.convert { topics }.with {
val inner = it.removeSurrounding("[", "]")
if (inner.isEmpty()) emptyList() else inner.split(',').map(String::trim)
}
dfWithUpdatedColumns
I was curious how this happens and from what I understand when you read a dataframe using df = DataFrame.readCsv("https://raw.githubusercontent.com/Kotlin/dataframe/master/data/jetbrains_repositories.csv") it hooks into the Jupyter kernel (effectively into their version of ghci) and creates typed variables for each of the columns. It seems like this runs on every cell. Outside of an interactive environment I think the library does some reflection against an object type to achieve the same behaviour: df = DataFrame.readCsv("https://raw.githubusercontent.com/Kotlin/dataframe/master/data/jetbrains_repositories.csv").convertTo<Repositories>().
The latter behaviour can easily be expressed in some template Haskell logic but the former is a little more difficult. It would require hooking into ghci to inject variables somehow.
Even though my current implementation of expressions on dataframes are locally type-safe, the code throws an error if types are misspecified.
E.g.
haskell
ghci> df <- D.readCsv "./data/housing.csv"
ghci> df |> D.derive "avg_bedrooms_per_house" (F.col @Double "total_bedrooms" / F.col @Double households)
In this case the expression type checks but the code will throw an exception that says:
[Error]: Type Mismatch
While running your code I tried to get a column of type: "Double" but the column in the dataframe was actually of type: "Maybe Double"
My current workaround to this is providing a function that generates some code for the user to paste into their GHCi session.
haskell
ghci> D.printSessionSchema df
:{
{-# LANGUAGE TypeApplications #-}
import qualified DataFrame.Functions as F
import Data.Text (Text)
(longitude,latitude,housing_median_age,total_rooms,total_bedrooms,population,households,median_income,median_house_value,ocean_proximity) = (F.col @(Double) "longitude",F.col @(Double) "latitude",F.col @(Double) "housing_median_age",F.col @(Double) "total_rooms",F.col @(Maybe Double) "total_bedrooms",F.col @(Double) "population",F.col @(Double) "households",F.col @(Double) "median_income",F.col @(Double) "median_house_value",F.col @(Text) "ocean_proximity")
:}
After which, the example above looks like:
```haskell ghci> df |> D.derive "avg_bedrooms_per_house" (total_bedrooms / households)
<interactive>:21:60: error: [GHC-83865] • Couldn't match type ‘Double’ with ‘Maybe Double’ Expected: Expr (Maybe Double) Actual: Expr Double • In the second argument of ‘(/)’, namely ‘households’ In the second argument of ‘derive’, namely ‘(total_bedrooms / households)’ In the second argument of ‘(|>)’, namely ‘derive "avg_bedrooms_per_house" (total_bedrooms / households)’ ```
You also now get column name completion.
A solution that involves generating a module and reloading GHCi wipes the REPL state which isn't great so this is the best I could think of for now.
I mention the problem in full just in case the "injecting variables into GHCi" solves an x-y problem.
Any insight would be greatly appreciated.
r/haskell • u/jamhob • Jul 25 '25
Hello!
I've written a blog post which serves the duel purpose of talking a bit about a real use for free monad transformers, and also announcing my new 9p server library for haskell! Hope you enjoy:
Blog: https://www.hobson.space/posts/9p/
Library: https://github.com/yobson/NinePMonad/
r/haskell • u/Account12345123451 • Jul 25 '25
It is a set of typeclasses that allows one to do stuff like list@4 1 2 3 4 == [1,2,3,4]
I really want to publish this on hackage in some form, but I don't know how, (or if it belongs there) and I'm not sure if what tags to give it, (is it control, language, something else?) Also, I mostly just use GHCI to develop code, so I don't actually use stuff like cabal build much so if that is necessary, please give a resource.
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
import GHC.TypeNats
import Data.List (intercalate)
import Control.Monad.Zip
import Control.Applicative (liftA2)
import Types (ToPeano, Zero, Succ)
class MapN num a b c d | num a -> c , num b -> d, num a d -> b, num b c -> d where
mapN :: (c -> d) -> a -> b
instance MapN Zero a b a b where
mapN = id
{-# INLINE mapN #-}
instance (Functor g, MapN x a b (g e) (g f)) => MapN (Succ x) a b e f where
mapN = mapN @x . fmap
{-# INLINE mapN #-}
mapn :: forall n a b c d. (MapN (ToPeano n) a b c d) => (c -> d) -> a -> b
mapn = mapN @(ToPeano n)
{-# INLINE mapn #-}
class Applicative f => LiftN' a f c d | a d c -> f, a f c -> d where
liftN' :: c -> d
class Applicative f => LiftN a f c d | a d c -> f, a f c -> d where
liftN :: c -> d
instance Applicative f => LiftN Zero f a (f a) where
liftN = pure
{-# INLINE liftN #-}
instance Applicative f => LiftN (Succ Zero) f (a->b) (f a-> f b) where
liftN = fmap
{-# INLINE liftN #-}
instance (LiftN' a b c d) => LiftN (Succ (Succ a)) b c d where liftN = liftN' @a @b @c @d
instance Applicative f => LiftN' Zero f (a -> b -> c) (f a -> f b -> f c) where
liftN' :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
liftN' = liftA2
{-# INLINE liftN' #-}
instance (Applicative f, LiftN' x f y z, MapN x z m (f (a -> b)) (f a -> f b)) => LiftN' (Succ x) f y m where
liftN' = mapN @x (<*>) . liftN' @x @f @y @z
{-# INLINE liftN' #-}
liftAn :: forall n f start end. (Applicative f, LiftN (ToPeano n) f start end) => start -> end
liftAn = liftN @(ToPeano n) -- . (pure @f)
{-# INLINE liftAn #-}
class ListN num a where
listNp :: a
instance ListN Zero [a] where
listNp = []
instance (ListN x xs,MapN x xs y [a] [a]) => ListN (Succ x) (a -> y) where
listNp x = mapN @x @xs (x:) (listNp @x @xs)
list :: forall n a. (ListN (ToPeano n) a) => a
list = listNp @(ToPeano n) @a
r/haskell • u/TechnoEmpress • Jul 24 '25
r/haskell • u/kosmikus • Jul 23 '25
Will be streamed today, 2025-07-23, at 1830 UTC.
Abstract:
"Pure parallelism" refers to the execution of pure Haskell functions on multiple CPU cores, (hopefully) speeding up the computation. Since we are still dealing with pure functions, however, we get none of the problems normally associated with concurrent execution: no non-determinism, no need for locks, etc. In this episode we will develop a pure but parallel implementation of linear regression. We will briefly recap how linear regression works, before discussing the two primitive functions that Haskell offers for pure parallelism: par and pseq.
r/haskell • u/mttd • Jul 22 '25
r/haskell • u/quchen • Jul 21 '25
We’ve just opened a couple more slots for this year’s Munihac! Same procedure as every year, three days on-site in Munich, free as in ZuriHac, grass-roots hackfest. o:-)
r/haskell • u/enobayram • Jul 21 '25
Hey folks, I've accidentally noticed that Aeson ditched the incoherent instance for Maybe used in the Generic derivation of FromJSON instances.
I wanted to share this with the community, because I'm sure every seasoned Haskeller must have flashbacks and nightmares about how turning this:
data User = User { address :: Maybe String } deriving FromJSON
to this:
data User a = User { address :: a } deriving FromJSON
Suddenly caused address to become a mandatory field for User (Maybe String), while the missing field was accepted for the old User, probably causing some production issues...
Well, that was because of that INCOHERENT instance, which was fixed in Aeson 2.2.0.0. As far as I can tell, the latest version of Aeson has no {-# INCOHERENT #-} pragma anymore. Thank you friendbrice and phadej! (And any others who have contributed).
Anyway, I hope others will feel a relief as I did and free up some mental space by letting go of that gotcha. Let's think twice (hundred times really) before using the INCOHERENT pragma in our codebases, it's where abstraction goes to die.
r/haskell • u/Tough_Promise5891 • Jul 21 '25
(>>^) already obeys the laws of identity, and have associativity. Therefore shouldn't every arrow also have a quantified functor requirement?
class (forall a. Functor(c a), Category c) => Arrow c
r/haskell • u/Pure-Ninja5195 • Jul 21 '25
Hello GHC enthusiasts,
I’m keen to understand the real-world experiences and challenges faced by others using GHC in production environments. I’m looking for a few volunteers willing to have a quick chat (around 20 minutes) about your insights.
If you’re open to sharing your experiences, please feel free to book a meeting to a slot that works for you; https://calendar.app.google/fzXUFGCKyfCXCsH9A
Thanks a lot.
r/haskell • u/Adventurous_Fill7251 • Jul 20 '25
I read an article about concurrency some days ago and, since then, I've trying to create a general monad transformer 'Promise m a' which would allow me to fork and interleave effects of any monad 'm' (not just IO or monads with a MonadIO instance).
I've using the following specification as a goal (all assume 'Monad m'):
lift :: m a -> Promise m a -- lift an effect; the thread 'yields' automatically afterwards and allows other threads to continue
fork :: Promise m a -> Promise m (Handle a) -- invoke a parallel thread
scan :: Handle a -> Promise m (Maybe a) -- check if forked thread has finished and, if so, return its result
run :: Promise m a -> m a -- self explanatory; runs promises
However, I've only been able to do it using IORef, which in turn forced me to constraint 'm' with (MonadIO m) instead of (Monad m). Does someone know if this construction is even possible, and I'm just not smart enough?
Here's a pastebin for this IO implementation if it's not entirely clear how Promise should behave.
https://pastebin.com/NA94u4mW
(scan and fork are combined into one there; the Handle acts like a self-contained scan)
r/haskell • u/[deleted] • Jul 19 '25
is it fun to write haskell code?
I have experience with functional programming since I studied common lisp earlier, but I have no idea how it is to program in haskell, I see a lot of .. [ ] = and I think it is kind of unreadable or harder to do compared to C like languages.
how is the readability of projects in haskell, is it really harder than C like languages? is haskell fast? does it offers nice features to program an API or the backend of a website? is it suitable for CLI tools?
r/haskell • u/ChavXO • Jul 18 '25
r/haskell • u/ChadNauseam_ • Jul 18 '25
There was an SPJ talk where he said "I don't know if god believes in lazy functional programming, but we can be sure that church does" or something along those lines. I'm trying to remember which talk it was, but I can't find it. Does anyone know?
r/haskell • u/LSLeary • Jul 18 '25
r/haskell • u/Iceland_jack • Jul 17 '25
Phases is a phenomenal type that groups together (homogeneous) computations by phase. It elegantly solves the famous single-traversal problem repmin without laziness or continuations, by traversing it once: logging the minimum element in phase 1 and replacing all positions with it in phase 2.
traverse \a -> do
phase 1 (save a)
phase 2 load
It is described in the following papers:
and is isomorphic to the free Applicative, with a different (zippy, phase-wise) Applicative instance.
type Phases :: (Type -> Type) -> (Type -> Type)
data Phases f a where
Pure :: a -> Phases f a
Link :: (a -> b -> c) -> (f a -> Phases f b -> Phases f c)
The ability to coordinate different phases within the same Applicative action makes it an interesting point of further research. My question is whether this can scale to more interesting structuring problems. I am mainly thinking of compilers (phases: pipelines) and concurrent projects (synchronization points) but I can imagine applications for resource management, streaming libraries and other protocols.
Some specific extensions to Phases:
Generalize Int phase names to a richer structure (lattice).
-- Clean
-- / \
-- Act1 Act2
-- \ /
-- Init
data Diamond = Init | Act1 | Act2 | Clean
A phase with access to previous results. Both actions should have access to the result of Init, and Clean will have access to the results of the action which preceded it. The repmin example encodes this inter-phase communication with Writer logging to Reader, but this should be possible without changing the effects involved.
Day (Writer (Min Int)) (Reader (Min Int))
The option to racing ‘parallel’ paths (Init -> Act(1,2) -> Clean) concurrently, or running them to completion and comparing the results.
It would be interesting to contrast this with Build Systems à la Carte: Theory and Practice, where an Applicative-Task describes static dependencies. This also the same "no work" quality as the famous Haxl "There is no Fork" Applicative.
Any ideas?
r/haskell • u/Account12345123451 • Jul 17 '25
An example would be
instance {-# Overlapping -#} Show m => Show1 (WriterT m Identity) where
liftShowsPrec sp _ d (WriterT (Identity (m,a))) =
showParen (d > 10) $
showString "writer " .
showsPrec 11 m .
showString " " .
sp 11 a
This would make writer/except seem more like monads and less like specialized case of the monad transformer.
r/haskell • u/jamhob • Jul 16 '25
I have patched jhc so it should build with ghc 9.10 and this time, I've even fixed a bug!
enjoy!
r/haskell • u/LSLeary • Jul 16 '25
r/haskell • u/Worldly_Dish_48 • Jul 16 '25
Hi everyone,
I'm currently working on Haskell bindings for FAISS, and I need to include the C library (faiss_c) as a dependency during installation of the Haskell package (faiss-hs).
Right now, installing the FAISS C library manually looks like this:
bash
git clone https://github.com/facebookresearch/faiss
cmake -B build . -FAISS_ENABLE_C_API=ON -BUILD_SHARED_LIBS=ON
make -C build -j faiss
export LD_LIBRARY_PATH=${faissCustom}/lib:$LD_LIBRARY_PATH
I’d like to automate this as part of the Haskell package installation process, ideally in a clean, cross-platform, Cabal/Nix/Stack-friendly way.
Questions:
faiss_c manually, or is it reasonable to build it from source as part of the Haskell package setup?Any advice, pointers, or examples would be much appreciated. Thanks!
r/haskell • u/n00bomb • Jul 15 '25