appInit :: SnapletInit App App
appInit = makeSnaplet "myapp" "My example app" Nothing $ do
hs <- nestSnaplet "heist" heist $ heistInit "templates"
fs <- nestSnaplet "foo" foo $ fooInit
bs <- nestSnaplet "" bar $ nameSnaplet "newname" $ barInit foo
addRoutes [ ("hello", writeText "hello world")
, ("fooname", with foo namePage)
, ("barname", with bar namePage)
, ("company", companyHandler)
]
wrapSite (<|> heistServe)
ref <- liftIO $ newIORef "fooCorp"
return $ App hs fs bs ref
Source: snap tutorial
map :: (a → b) → F a → F b
Integer length(String str) { ... }
Stream<String> names = Stream.of("Adil", "Aline");
Stream<Integer> nameLengths = names.map(::length);
length :: String → Integer
names :: List String
nameLengths :: List Integer
nameLengths = length <$> names
isLongEnough :: String → Boolean
hasSymbol :: String → Boolean
hasDigit :: String → Boolean
validate :: String → Array Boolean
validate input = [isLongEnough, hasSymbol, hasDigit] <@> input
"inherits" from Functor
<*> = apply :: F (a → b) → F a → F b
Date getDate(Day day, Month month) { ... }
Optional<Day> day = ...;
Month month = Month.July;
Optional<Date> date = day.map(day → getDate(day, month));
Note: Java does not provide tools like apply
getDate :: Day → Month → Date
maybeDay :: Maybe Day -- Just 1 | Nothing
month = July
getDate <$> maybeDay :: Maybe (Month → Date)
maybeDate :: Maybe Date
maybeDate = getDate <$> maybeDay <*> Just month
An idea on how to improve the last line?
(replacing the <*> with ...)
lift2 :: (a → b → c) → F a → F b → F c
"inherits" from Apply
pure :: a -> F a
Optional<String> opt = Optional.of("hello");
Stream<String> str = Stream.of("hello");
Why are they not strictly Applicatives?
pure "hello" :: Maybe String
pure "hello" :: List String
"inherits" from Apply
>>= bind :: F a → (a → F b) → F b
Optional<Date> parseDate(String str) { ... }
Optional<String> input = getInput();
Optional<Date> date = input.flatMap(str → parseDate(str));
parseDate :: String → Maybe Date
input = getInputFromUnknownSource :: Maybe String
maybeDate = input >>= parseDate
maybeDate = do
input ← getInputFromUnknownSource
parseDate input
parseDate :: String → Maybe Date
getSubscription :: Date → Maybe Subscription
getFare :: Subscription → Maybe Money
getFareFromDate input =
(parseDate >=> getSubscription >=> getFare) input
Do you remember how we simplified this at the very beginning?
"inherits" from Bind and Applicative
[mind blowing gif]
Functional languages are made for composition