Syntactic Cheat Sheet
Translating from TypeScript to Haskell
TypeScript
Haskell
// This is a TypeScript comment
/*
Need more space?
No problem!
This is a multi-line TypeScript comment :)
*/
/**
* In TS, you write documentation like this for TypeDoc
*/
const id = a => a
-- This is a Haskell comment
{-
Need more space?
No problem!
This is a multi-line Haskell comment :)
-}
--| Add a pipe for a short function description
-- You can keep talking about is afterwards
-- These will turn into formatted documentation with Haddock
id a = a
{-| You can use a multi-line comment for Haddock, too
The same rules apply.
-}
swap (a, b) -> (b, a)
TypeScript
Haskell
const hi = "Hello World"
hi = "Hello World"
TypeScript
Haskell
Haskell (Local Clarification Variant)
const hi: string = 'Hello World'
hi :: Text
hi = "Hello World"
hi = ("Hello World" :: Text)
TypeScript
Haskell
Haskell (Shorthand)
a => a * 2
\a -> a * 2
-- NOTE: `\` is an easier to type lambda `λ`
(*2)
TypeScript
Haskell
Haskell (Shorthand)
const double = (a : number) => a * 2
double :: Int -> Int
double a = a * 2
double :: Int -> Int
double = (*2)
TypeScript
Haskell
// Does not exist
(*&) :: Int -> String -> String
num *& str = show num ++ str
-- NOTE: `show` turns values into strings
TypeScript
Haskell
const result = doTheThing(1, 2, ["a", "b"], 1.1)
result = doTheThing 1 2 ["a", "b"] 1.1
TypeScript
Haskell
fireTheMissiles()
fireTheMissiles
TypeScript
Haskell (let...in)
Haskell (where)
const withInner = (toLog: string): void => {
const innerValue = 'That is the question!'
console.log(`${toLog}? Or not ${toLog}? ${innerValue}`)
}
withInner' toLog =
let
innerValue = "That is the question!"
msg = toLog <> "? Or not " <> toLog <> "? " <> innerValue
in
logInfo msg
withInner toLog = logInfo msg
where
msg = toLog <> "? Or not " <> toLog <> "? " <> innerValue
innerValue = "That is the question!"
TypeScript
Haskell (parens)
Haskell (applied with $)
Haskell (Piped with &)
const result = triple(prod(1, double(1), 3))
/* i.e.
const two = double(1)
const six = prod(1, two, 3)
const result = triple(six)
*/
result = triple (prod 1 (double 1) 3)
result = triple $ prod 1 (double 1) 3
result = 3
& prod 1 (double 1)
& triple
TypeScript
Haskell
const timesSix = (a: number): number => triple(double(a))
timesSix :: Int -> Int
timeSix = triple . double
TypeScript
Haskell
Haskell (Point-Free Style)
const math = (n: number, m: number): number =
triple(prod(10, double(1), n), m)
math :: Int -> Int -> Int
math n m = triple (prod 10 (double 1) n) m
math :: Int -> Int -> Int
math = triple . prod 10 (double 1)
TypeScript
Haskell
import * from "./GetEverything"
import * as HL from "./HelperLib";
import { foo, bar } from "./SomeLib"
const id = a => a
const swap = ([a, b]) => [b, a]
const hiddenValue = HL.downcase("not exported")
export {
id,
swap
}
export { toReExport } from "./ExternalLib"
module MyModule
( id
, swap
, toReExport
) where
import GetEverything
import SomeLib (foo, bar)
import ExternalLib (toReExport)
import qualified HelperLib as HL
id a = a
swap (a, b) = (b, a)
hiddenValue = HL.downcase "not exported"
TypeScript
Haskell
type Name = string
type Balance = number
type Name = Text
type Balance = Int
TypeScript
Haskell
type TrafficLight = 'RED' | 'YELLOW' | 'GREEN'
data TrafficLight
= Red
| Yellow
| Green
TypeScript
Haskell
type GearRatio = [number, number] // [big gear, little gear]
type Bike = [string, GearRatio] // [bikeName, gear ratio]
data GearRatio = GearRatio Int Int
data Bike = Bike Text GearRatio
TypeScript (Interface)
TypeScript (Class)
Haskell
interface GearRatio {
big: number
little: number
}
interface Bike {
name: string
gear: GearRatio
}
class Geared {
big: number
little: number
constructor(gbr: number, lgr: number) {
big = bgr
little = lgr
}
}
class Bike extends Geared {
name: string
constructor(bgr: number, lgr: number, bikeName: string) {
name = bikeName
super(bgr, lgr)
}
}
data Gear = GearRatio
{ _big :: Natural
, _little :: Natural
}
data Bike = Bike
{ _name :: Text
, _gear :: Gear
}
TypeScript (Direct)
TypeScript (Class)
Haskell
const makeGear = (big, little): GearRatio => ({ big, little })
const makeBike = (big, little, name): Bike => ({
name,
gear = makeGear(big, little)
})
/*
Included in the `class` delcaration. For example:
constructor(bgr: number, lgr: number) {
big = bgr
little = lgr
}
*/
{-
Constructors are the capitalized word on
the right of the `=` in the `data` declaration
It auto-generates constructor functions
with the folling type signatures:
GearRatio :: Natural -> Natural -> Geared
Bike :: Text -> GearRatio -> Bike
-}
TypeScript (Direct)
TypeScript (Class)
Haskell
Haskell (Record Style)
Haskell (Wildcard Style)
const myBike = makeBike(2, 5, '10 Speeder')
const myBike = new Bike(2, 5, '10 Speeder')
myBike = Bike "10 Speeder" (GearRatio 2 5)
myBike = Bike
{ _name = "10 Speeder" -- Use named fields
, _gear = GearRatio 2 5 -- Or just ordered values
}
myBike :: Bike
myBike =
let
_big = 2
_little = 5
_name = "10 Speeder"
_gear = GearRatio {..}
in
Bike {..}
TypeScript (Dot Syntax)
TypeScript (Destructuring)
Haskell (Destructuring)
Haskell (Wildcard Style)
Haskell (Lenses)
const big: number = myGears.big
const little = myBike.gear.little
const { bigGear } = myGears
const getBig = ({ big }) => big
const ratio = ({ big, little }) => big / little
GearRatio big _ = myGears
getBig (GearRatio {_big}) = _big
ratio (GearRatio {_big, _little}) = _big / _little
ratio (GearRatio {..}) = _big / _little
import Control.Lens.TH
$(makeLenses ''Gear)
$(makeLenses ''Bike)
myGear ^. big -- NOTE: lenses have no underscores!
-- Nested
myBike ^. gear . little
TypeScript
Haskell (Record Syntax)
Haskell (Lenses)
// Preamble
const myGear = new GearRatio(2, 5)
const myBike = new Bike('10 Speeder', myGear)
// Mutable Update
myGear.littleGear = 6
myBike.name = '12 Speeder'
// Immutable Update
const upgradedGear = Object.assign({}, myGear)
const upgradedBike = Object.assign({}, myBike, {gear: upgradedGear})
-- Preamble
myGear = GearRatio 2 5
myBike = Bike "10 Speeder" myGear
-- Immutable Update
upgradedBike = myBike
{ _name = "12 Speeder"
, _gear = myGear { _littleGear = 6 }
}
-- Preamble
import Control.Lens.TH
makeLenses ''Gear
makeLenses ''Bike
myGear = GearRatio 2 5
myBike = Bike "10 Speeder" myGear
-- Immutable Update
upgradedBike = myBike & name .~ "12 Speeder"
& gear.littleGear .~ 6
TypeScript
TypeScript Ternary
Haskell
if (condition) {
branchA
} else {
branchB
}
condition ? branchA : branchB
if condition
then branchA
else branchB
TypeScript
Haskell
if (percent >= 90 || student.paidBribe) {
return GRADES.A
} else if (percent >= 75) {
return GRADES.B
} else if (percent >= 60) {
return GRADES.C
} else if (percent >= 50) {
return GRADES.D
} else {
return GRADES.F
}
if | percent >= 90 || paidBribe student = A
| percent >= 75 = B
| percent >= 60 = C
| percent >= 50 = D
| otherwise = F
TypeScript
Haskell
let nextAction
switch (lightState) {
case LIGHT.RED:
nextAction = ACTION.STOP
break
case LIGHT.YELLOW:
nextAction = ACTION.SLOW
break
case LIGHT.GREEN:
nextAction = ACTION.DRIVE
break
default:
nextAction = currentAction
}
nextAction =
case lightState of
Red -> Stop
Yellow -> Slow
Green -> Drive
_ -> currentAction
Last modified 4yr ago