# Would keyword arguments conflict with currying in Haskell?

**URL:** <https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906>\
**Category:** Learn\
**Created:** [April 8, 2026, 6:19am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906 "2026-04-08T06:19:35Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shantanu-sg-01](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/shantanu-sg-01/32/5011_2.png) [@Shantanu-sg-01](https://discourse.haskell.org/u/Shantanu-sg-01)\
**Post date:** [April 8, 2026, 6:19am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/1 "2026-04-08T06:19:35Z")

</div>

Hi all,

I was thinking about keyword arguments (like in Python) and why Haskell doesn’t support them.

It seems that keyword arguments could improve readability at the call site, especially when multiple parameters have similar types. However, Haskell relies heavily on currying and partial application, where functions are applied one argument at a time.

So my question is:

Would adding keyword arguments conflict with currying in Haskell?

For example, how would partial application work if arguments could be passed out of order or by name?

Is this one of the main reasons Haskell avoids keyword arguments, or are there deeper design considerations?

Also, are records essentially the intended alternative here?

Thanks!

---

<div class="post-metadata">

**Author:** ![dyaitskov](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/dyaitskov/32/5142_2.png) [@dyaitskov](https://discourse.haskell.org/u/dyaitskov)\
**Post date:** [April 8, 2026, 6:54am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/2 "2026-04-08T06:54:26Z")

</div>

> [@Shantanu-sg-01](#):
>
> Would adding keyword arguments conflict with currying in Haskell?

File a [proposal](https://github.com/ghc-proposals/ghc-proposals) to get thorough feedback.

Arguments of same type can be disambiguated with phantom types trick.

```haskell
{-# LANGUAGE TypeApplications #-}
import Data.Tagged

data A
data B 

f :: Tagged A Int -> Tagged B Int -> Int
f (Tagged a) (Tagged b) = a + b

withF :: Int
withF = f (pure @A 1) (pure @B 2)

```

---

<div class="post-metadata">

**Author:** ![jaror](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jaror/32/3271_2.png) [@jaror](https://discourse.haskell.org/u/jaror)\
**Post date:** [April 8, 2026, 8:09am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/3 "2026-04-08T08:09:11Z")

</div>

I think I would restrict it to functions having either keyword arguments or positional arguments, so forbidding a combination of the two. In that case you could just consider a function with keyword arguments to be a function from a record type. For example my imagined syntax would be:

```haskell
magnitude :: {x :: Int, y :: Int} -> Double
magnitude {x = x, y = y} = sqrt (fromIntegral (x * x + y * y))

```

That could be desugared into:

```haskell
data MagnitudeArg = MkMagnitudeArg { x :: Int, y :: Int }

magnitude :: MagnitudeArg -> Double
magnitude MkMagnitudeArg {x = x, y = y} = sqrt (fromIntegral (x * x + y * y))

```

In the [Purescript](https://www.purescript.org/) Haskell dialect you can already write such functions using anonymous records:

```haskell
magnitude :: {x :: Number, y :: Number} -> Number
magnitude {x, y} = sqrt (x * x + y * y)

```

And there is a proposal to add support for it to GHC (although it is a lot more ambitious):

> <https://github.com/ghc-proposals/ghc-proposals/pull/180>
>
> Record types in Haskell are just syntactic sugar over normal product types, this… prevents us from specifying functions that work for certain structures of records.
> \[Rendered\](https://github.com/jvanbruegge/ghc-proposals/blob/row-polymorphism/proposals/0000-row-polymorphism.rst)

---

<div class="post-metadata">

**Author:** ![BurningWitness](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/burningwitness/32/3665_2.png) [@BurningWitness](https://discourse.haskell.org/u/BurningWitness)\
**Post date:** [April 8, 2026, 8:21am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/4 "2026-04-08T08:21:34Z")

</div>

But then writing `magnitude { x = .., y = .. }` would be ambiguous due to record update syntax, so [deprecating record update syntax](https://discourse.haskell.org/t/rfc-mutable-records-as-a-ghc-extension/13886/6) could fix that as well.

---

<div class="post-metadata">

**Author:** ![jaror](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jaror/32/3271_2.png) [@jaror](https://discourse.haskell.org/u/jaror)\
**Post date:** [April 8, 2026, 8:25am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/5 "2026-04-08T08:25:16Z")

</div>

I feel like GHC should be able to tell that `magnitude` is a function with named arguments and treat it differently based on that. Though that can indeed be confusing.

---

<div class="post-metadata">

**Author:** ![BurningWitness](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/burningwitness/32/3665_2.png) [@BurningWitness](https://discourse.haskell.org/u/BurningWitness)\
**Post date:** [April 8, 2026, 11:21am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/6 "2026-04-08T11:21:00Z")

</div>

There’d probably be some issues with type resolution I’m not aware of, but to me the main confusion would come from there effectively being two different types of record syntax. The one for partial record update is almost never used over all arguments (because it’s partial), whereas one for providing function arguments has to provide all arguments (because syntactically they can be provided in any order, so leaving any of them out to be provided positionally would be confusing/ambiguous).

---

<div class="post-metadata">

**Author:** ![chrisdone](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/chrisdone/32/1408_2.png) [@chrisdone](https://discourse.haskell.org/u/chrisdone)\
**Post date:** [April 9, 2026, 7:02am UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/7 "2026-04-09T07:02:55Z")

</div>

OCaml has named params too and others mentioned above.

A recent mention is in the Coalton language

[https://coalton-lang.github.io/20260312-coalton0p2/#keyword-arguments](https://coalton-lang.github.io/20260312-coalton0p2/#keyword-arguments)

---

<div class="post-metadata">

**Author:** ![absurdvoid](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@absurdvoid](https://discourse.haskell.org/u/absurdvoid)\
**Post date:** [April 10, 2026, 6:50pm UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/8 "2026-04-10T18:50:53Z")

</div>

> [@Shantanu-sg-01](#):
>
> Would adding keyword arguments conflict with currying in Haskell?
> 
> For example, how would partial application work if arguments could be passed out of order or by name?

I don’t think it would necessarily conflict with currying. I imagine it could work as a bit of syntactic sugar, e.g.

```haskell
httpRequest :: String -> Method -> Maybe Body -> IO Response
httpRequest url method body = ...

-- Partially apply the function with a keyword argument
httpRequest method:POST

-- ... which would desugar to
\url body -> httpRequest url POST body

```

Something like the above could still be curried as usual:

```haskell
mapM (httpRequest body:Nothing method:GET) 
  [ "https://example.com",
    "https://google.com",
    ...
  ]

```

That said, this only works if all keyword arguments are mandatory. _Optional_ keyword arguments would be more complicated since it would be ambiguous whether we intend to call with defaults or want to wait for the rest of the arguments. This could potentially be disambiguated based on where/how the function is used or explicitly via some extra syntax.

---

<div class="post-metadata">

**Author:** ![brandonchinn178](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/brandonchinn178/32/5103_2.png) [@brandonchinn178](https://discourse.haskell.org/u/brandonchinn178)\
**Post date:** [April 12, 2026, 4:15pm UTC](https://discourse.haskell.org/t/would-keyword-arguments-conflict-with-currying-in-haskell/13906/9 "2026-04-12T16:15:01Z")

</div>

The difficult part is what if you have functions with multiple bodies, or functions that pattern match args immediately?

```haskell
foo :: Foo -> Bar -> Int
foo Foo{a, b = 123} bar1 = a
foo Foo{a, b} bar2 = other b

```

I would also want the ability to separate “the keyword arg callers must use” from “name of local var I’m assigning to this arg”.

I think a syntax like this could be interesting:

```haskell
foo :: a:Foo -> b:Bar -> Int
foo Foo{} bar = ...

```
