Created
January 25, 2020 15:05
-
-
Save i-am-the-slime/00d60352d6c8aa3e6713dd4654495ce8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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