Skip to content

Scrap Distribution.Compat.Newtype#12126

Open
Bodigrim wants to merge 1 commit into
masterfrom
newtypes
Open

Scrap Distribution.Compat.Newtype#12126
Bodigrim wants to merge 1 commit into
masterfrom
newtypes

Conversation

@Bodigrim

@Bodigrim Bodigrim commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

This module was derived from https://hackage.haskell.org/package/newtype, which predates introduction of class Coercible to GHC, a more modern and better known alternative.

The class Newtype served to provide rather awkward combinators:

  • ala :: (Newtype o n, Newtype o' n') => (o -> n) -> ((o -> n) -> b -> n') -> b -> o'
  • alaf :: (Newtype o n, Newtype o' n') => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'
  • pack' :: Newtype o n => (o -> n) -> o -> n
  • unpack' :: Newtype o n => (o -> n) -> n -> o

What is awkward about them? All of them completely ignore the first argument and never apply it to the value. The argument serves purely to provide a type annotation in an ancient epoch predating {-# LANGUAGE TypeApplication #-}. (Even this could have been done better by using proxy a b instead of (->) a b in type signatures, to signalize that the argument is not going to be applied to anything).

Haskell acquired class Coercible a b where coerce :: a -> b after 2011 and by now it is a standard way to deal with newtypes, reducing cognitive overhead for developers.

Please read Github PR Conventions and then fill in one of these two templates.


Template Α: This PR modifies behaviour or interface

This module was derived from https://hackage.haskell.org/package/newtype,
which predates introduction of `class Coercible` to GHC,
a more modern and better known alternative.

The `class Newtype` served to provide rather awkward combinators:
* `ala :: (Newtype o n, Newtype o' n') => (o -> n) -> ((o -> n) -> b -> n') -> b -> o'`
* `alaf :: (Newtype o n, Newtype o' n') => (o -> n) -> ((a -> n) -> b -> n') -> (a -> o) -> b -> o'`
* `pack' :: Newtype o n => (o -> n) -> o -> n`
* `unpack' :: Newtype o n => (o -> n) -> n -> o`

What is awkward about them? All of them completely ignore the first argument and never apply it to the value.
The argument serves purely to provide a type annotation in an ancient epoch predating `{-# LANGUAGE TypeApplication #-}`.
(Even this could have been done better by using `proxy a b` instead of `(->) a b` in type signatures, to signalize
that the argument is not going to be applied to anything).

Haskell acquired `class Coercible a b where coerce :: a -> b` after 2011
and by now it is a standard way to deal with newtypes, reducing cognitive overhead for developers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant