Skip to content

Instantly share code, notes, and snippets.

@i-am-the-slime
Created January 25, 2020 15:05
Show Gist options
  • Save i-am-the-slime/00d60352d6c8aa3e6713dd4654495ce8 to your computer and use it in GitHub Desktop.
Save i-am-the-slime/00d60352d6c8aa3e6713dd4654495ce8 to your computer and use it in GitHub Desktop.
module Main (main) where
import Prelude
import Data.Foldable (traverse_)
import Data.Function.Uncurried (Fn2, runFn2)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.String (toUpper)
import Data.Time.Duration (Milliseconds(..))
import Effect (Effect)
import Effect.Aff (Aff, delay)
import Effect.Class.Console (logShow)
import Effect.Console (log)
import Milkis (URL(..), getMethod, text)
import Milkis as M
import Milkis.Impl.Node (nodeFetch)
import Record (insert, merge)
import Type.Prelude (SProxy(..))
main :: Effect Unit
main = do
log "Hi!"
--| Basics
-- A value
number = 5.0
-- A function
add number1 number2 = number1 + number2
alsoAdd = \number1 number2 -> number1 + number
-- Some names are different
toString = show
some = Just
none = Nothing
getOrElse = fromMaybe
-- but the concepts are the same
theSame = some(12) == Just 12
theSameToo = (some(12)#getOrElse(4)) == fromMaybe 4 (Just 12)
-- money is important
withParentheses = show (Just 4)
withDollar = show $ Just 4
withPound = Just 4 # show
-- making some data
data Mammal = Cat | Dog
-- Pattern matching
talk mammal = case mammal of
Cat -> "meow"
Dog -> "woof"
-- making data with data in it
data Person = PersonConstructor String Int
-- making better data with data in it
newtype Name = NameConstructor String
-- usually the constructor name is the same as the type
newtype Age = Age Int
safeAge age = if age > 0 && age < 120 then Just (Age age) else Nothing
data Person' = Person' Name Age
-- an alternative with records
type ReasonablePerson =
{ name :: String
, age :: Int
}
-- or the megasafe version
newtype FoolproofPerson = FoolproofPerson
{ name :: Name
, age :: Age
}
-- create a reasonable person
rp = { name: "Heinz", age: 58 }
-- update it
rpOlder :: ReasonablePerson
rpOlder = rp { age = rp.age + 1 }
type DetailedPerson =
{ name :: String
, age :: Int
, address :: String
, hobbies :: Array String
}
detailedPerson :: DetailedPerson
detailedPerson =
merge rp { address: "Universe", hobbies: ["PureScript"]}
-- The same is possible with Sum Types (Polymorphic Variants) which is great for error handling
-- Type annotations
aString :: String
aString = "A String"
aFunction :: Int -> Int
aFunction n = n + 2
anotherFunction :: Int -> (Int -> Int)
anotherFunction n m = n + m
-- Calling JS
foreign import valueFromJs :: Int
foreign import functionFromJs :: Int -> Int
foreign import leftPad :: Int -> String -> String
-- Alternative for more readable JS
foreign import leftPadUncurried :: Fn2 Int String String
leftPad' :: Int -> String -> String
leftPad' = runFn2 leftPadUncurried
foreign import data MyClass :: Type
foreign import newMyClass :: MyClass
foreign import initMyClass :: MyClass -> Effect Unit
-- Effects
println :: String -> Effect Unit
println = log
-- Effect is simply a function with 0 arguments at runtime
foreign import jsEffect :: Effect Unit
-- Concurrent Effects
wait :: Milliseconds -> Aff Unit
wait ms = delay ms
googleSomethingOptimistically :: Aff String
googleSomethingOptimistically = do
response <- fetch (URL "https://www.google.com/q=purescript") { method: getMethod }
text response
-- Advanced
-- Polymorphic functions
myIdentity :: forall a. a -> a
myIdentity x = x
-- Typeclass constraints
toStringAgain :: forall a. Show a => Eq a => a -> String
toStringAgain = show
-- Row types
capitaliseName :: forall r. { name :: String | r } -> { name :: String | r }
capitaliseName record = record { name = toUpper record.name }
screamHeinz = capitaliseName { name: "Heinz" }
screamOther = capitaliseName { name: "Dembowski", age: 98 }
addAgeToRecord age record = insert (SProxy :: _ "age") age record
withAge = addAgeToRecord 34 { does: "n't", matter: 4.2 }
-- exceptIfItAlreadyHasAge = addAgeToRecord 34 { age: 12, matter: 4.2 }
-- Utils
fetch = M.fetch nodeFetch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment