| CARVIEW |
Select Language
HTTP/1.1 200 OK
Connection: keep-alive
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html; charset=utf-8
Cache-Control: public, max-age=300
Content-Encoding: gzip
Via: 1.1 varnish, 1.1 varnish
Accept-Ranges: bytes
Age: 0
Date: Sat, 17 Jan 2026 15:09:04 GMT
X-Served-By: cache-dfw-kdfw8210158-DFW, cache-bom-vanm7210046-BOM
X-Cache: MISS, MISS
X-Cache-Hits: 0, 0
X-Timer: S1768662544.322713,VS0,VE473
Vary: Accept, Accept-Encoding
transfer-encoding: chunked
type-machine: Type-level functions for record types
type-machine: Type-level functions for record types
Modules
[Index] [Quick Jump]
Downloads
- type-machine-0.1.0.2.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)
Maintainer's Corner
For package maintainers and hackage trustees
Candidates
- No Candidates
| Versions [RSS] | 0.1.0.0, 0.1.0.1, 0.1.0.2 |
|---|---|
| Change log | CHANGELOG.md |
| Dependencies | base (>=4.7 && <5), containers (>=0.7 && <0.9), mtl (>=2.3.1 && <2.4), syb (>=0.7.2 && <0.7.3), template-haskell (>=2.22 && <2.24), type-machine [details] |
| License | BSD-3-Clause |
| Copyright | 2025 Arthi-chaud |
| Author | Arthi-chaud |
| Maintainer | aj530@kent.ac.uk |
| Uploaded | by ArthiChaud at 2025-09-02T10:46:24Z |
| Category | Types |
| Home page | https://github.com/Arthi-chaud/type-machine#readme |
| Bug tracker | https://github.com/Arthi-chaud/type-machine/issues |
| Source repo | head: git clone https://github.com/Arthi-chaud/type-machine |
| Distributions | NixOS:0.1.0.2 |
| Executables | vector-example |
| Downloads | 36 total (11 in the last 30 days) |
| Rating | 2.0 (votes: 1) [estimated by Bayesian average] |
| Your Rating |
|
| Status | Docs uploaded by user Build status unknown [no reports yet] |
Readme for type-machine-0.1.0.2
[back to package description]Type Machine
TypeScript offers Utility Types, which allows creating a type from another. There is no way of doing this in Haskell. You have to maintain all your types yourselves, and handle conversions from one to another yourself.
type-machine brings a solution to this problem. Using Template Haskell, generate new types using Type-Script-inspired functions like omit, pick and record.
It can also generate a conversion type-class that allows you to access fields and convert one type to another.
- Requirements
- Requires a couple of language extensions (see example)
- Input ADT must have exactly one record constructor
- Limitations
- Does not support type parameters yet
requireandpartialonly work withMaybefields
Examples
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DuplicateRecordFields #-}
data User = User {
id :: Int,
name :: String,
email :: Maybe String
}
$(type_ "UserWithEmail" (required ["email"] <::> ''User))
-- data UserWithEmail = UserWithEmail {
-- id :: Int,
-- name :: String,
-- email :: String
-- }
$(type_ "UserWithoutId" (omit ["id"] <::> ''User))
-- data UserWithoutId = UserWithoutId {
-- name :: String,
-- email :: String
-- }
$(type_ "UserId" (pick ["id"] <::> ''User))
-- data UserId = UserId {
-- id :: Int
-- }
$(type_ "Vector3" (record ["x", "y", "z"] [t|Int|]))
-- data Vector3 = Vector3 {
-- x :: Int,
-- y :: Int,
-- z :: Int
-- }
-----
-- Type Parameters
-----
data MyMaybe a = { content :: Maybe a }
$(type_ "MyString" (apply [t|String|] <::> ''MyMaybe))
-- data MyString = MyString {
-- content :: Maybe String
-- }
-----
-- Is
-----
$(declareIs ''User)
-- class IsUser a where
-- getId :: a -> Int
-- getName :: a -> String
-- getEmail :: a -> String
-- setId :: Int -> a -> a
-- setName :: String -> a -> a
-- setEmail :: String -> a -> a
--
-- instance IsUser User where
-- getId = id
-- getName = name
-- getEmail = email
-- setId = ...
-- setName = ...
-- setEmail = ...
$(type_ "UserWithoutEmail" (omit ["email"] <::> ''User))
$(deriveIs ''User ''UserWithoutEmail)
-- instance IsUser UserWithoutEmail where
-- ...
$(type_ "UserWithoutId" (omit ["id"] <::> ''User))
$(deriveIs ''User ''UserWithoutId) -- Will fail