| 1 |
module Main where |
| 2 |
|
| 3 |
import Data.Either (Either(..)) |
| 4 |
import Data.Eq (class Eq) |
| 5 |
import Data.Function.Uncurried (Fn2, mkFn2, runFn2) |
| 6 |
import Data.List (List(..), filter, (:)) |
| 7 |
import Data.Maybe (Maybe(..)) |
| 8 |
import Data.String.Regex (Regex, parseFlags, regex, replace) |
| 9 |
import Effect (Effect) |
| 10 |
import Effect.Console (log, logShow) |
| 11 |
import Partial.Unsafe (unsafePartial) |
| 12 |
import Prelude (Unit, discard, map, mod, show, (+), (==), ($), (/=), (<>)) |
| 13 |
|
| 14 |
type Dict key value = key → Maybe value |
| 15 |
|
| 16 |
emptyDict :: ∀ k v. Dict k v |
| 17 |
emptyDict _ = Nothing |
| 18 |
|
| 19 |
insertDict :: ∀ k v. (Eq k) => k → v → Dict k v → Dict k v |
| 20 |
insertDict key value dict = |
| 21 |
\key' → if key == key' |
| 22 |
then (Just value) |
| 23 |
else dict key' |
| 24 |
|
| 25 |
|
| 26 |
-- | Take a look at src/Main.js to see how we curry arguments |
| 27 |
-- | in Javascript |
| 28 |
foreign import myAdd :: Int → Int → Int |
| 29 |
|
| 30 |
-- | When performance is critical then use Data.Function.Uncurried |
| 31 |
myAddFast :: Fn2 Int Int Int |
| 32 |
myAddFast = mkFn2 \x y → x + y |
| 33 |
|
| 34 |
add10 :: Int -> Int |
| 35 |
add10 = myAdd 10 |
| 36 |
|
| 37 |
modulo :: Int -> Int -> Int |
| 38 |
modulo dvr dvd = dvd `mod` dvr |
| 39 |
|
| 40 |
isOdd :: Int -> Int |
| 41 |
isOdd = modulo 2 |
| 42 |
|
| 43 |
getAllOdds :: List Int -> List Int |
| 44 |
getAllOdds = filter (\x -> isOdd x /= 0) |
| 45 |
|
| 46 |
regexString :: Regex |
| 47 |
regexString = |
| 48 |
unsafePartial |
| 49 |
case (regex "[aeiou]" (parseFlags "ig")) of |
| 50 |
Right r -> r |
| 51 |
|
| 52 |
censor :: String -> String |
| 53 |
censor = replace regexString "*" |
| 54 |
|
| 55 |
censorAll :: Array String -> Array String |
| 56 |
censorAll = map censor |
| 57 |
|
| 58 |
main :: Effect Unit |
| 59 |
main = do |
| 60 |
log "Build curried functions" |
| 61 |
log "\nAdvantage 1: Partially applying functions" |
| 62 |
log $ "myAdd: " <> (show $ myAdd 2 2) |
| 63 |
log "\nAdvantage 2: function types" |
| 64 |
-- notice key' == key ('a' == 'a'), so return Just 1 |
| 65 |
logShow $ (insertDict 'a' (1::Int) emptyDict) 'a' |
| 66 |
-- search for 'a' in Dict and return its value |
| 67 |
logShow $ insertDict 'b' 2 (insertDict 'a' (1::Int) emptyDict) 'a' |
| 68 |
-- the 'x' key is not in Dict, so fall back to Nothing |
| 69 |
logShow $ insertDict 'b' 2 (insertDict 'a' (1::Int) emptyDict) 'x' |
| 70 |
log "\nCurrying Examples: add10, isOdd, isOdd21, getAllOdds" |
| 71 |
logShow $ add10 2 |
| 72 |
logShow $ isOdd 2 |
| 73 |
logShow $ isOdd 21 |
| 74 |
logShow $ getAllOdds (1 : 2 : 3 : 4 : Nil) |
| 75 |
log "\nBuild up predicate functions" |
| 76 |
log $ censor "hello world" |
| 77 |
logShow $ censorAll ["hello", "world"] |
| 78 |
log "\nUse Data.Function.Uncurried when performance is critical" |
| 79 |
logShow $ runFn2 myAddFast 10 10 |
| 80 |
|
| 81 |
-- From https://github.com/adkelley/javascript-to-purescript/blob/master/tut17/src/Main.purs |
| 82 |
|