This commit is contained in:
Orion Kindel 2024-09-24 14:53:59 -05:00
parent 3701b1e2f8
commit d74fc46755
Signed by untrusted user who does not match committer: orion
GPG Key ID: 6D4165AE4C928719
30 changed files with 233 additions and 46 deletions

View File

@ -2,5 +2,6 @@
"theme": "obsidian",
"accentColor": "#745eff",
"interfaceFontFamily": "",
"baseFontSize": 20
"baseFontSize": 22,
"nativeMenus": false
}

View File

@ -17,6 +17,6 @@
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 0.6174207201407237,
"scale": 0.36924895020525084,
"close": true
}

View File

@ -4,11 +4,11 @@
"type": "split",
"children": [
{
"id": "1ae4bfe7bb551ca1",
"id": "eecc282740820263",
"type": "tabs",
"children": [
{
"id": "d3a2cb4690ca618a",
"id": "6465d16034124b8f",
"type": "leaf",
"state": {
"type": "graph",
@ -65,8 +65,7 @@
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
"width": 300
},
"right": {
"id": "75cf567121b661bb",
@ -141,12 +140,32 @@
"publish:Publish changes...": false
}
},
"active": "d3a2cb4690ca618a",
"active": "6465d16034124b8f",
"lastOpenFiles": [
"Classes/Alternative/Alt.md",
"Classes/Alternative/Plus.md",
"Monads/Transformers/MaybeT.md",
"Monads/Transformers/ExceptT.md",
"Monads/Transformers/ReaderT.md",
"Monads/Transformers/WriterT.md",
"Monads/Transformers/StateT.md",
"Monads/Transformers",
"Classes/Alternative/Alternative.md",
"Classes/Functor/Applicative.md",
"Classes/Functor/Apply.md",
"Classes/Functor/Functor.md",
"Classes/Collapsing",
"Classes/Bind",
"Classes/Functor",
"Classes/Alternative",
"Language/Infix Operators/Common Operators/Data.md",
"Classes/Traversable.md",
"Data/Collections/NonEmptyArray.md",
"Data/Collections/NonEmptyList.md",
"Data/String.md",
"Data/Collections.md",
"Data/Collections/HashMap.md",
"Data/Product",
"Data/Untitled.md",
"Data/Sum",
"Data/Collections/HashSet.md",
"Data/Collections/Set.md",
@ -158,27 +177,7 @@
"Language/Row Types/Record.md",
"Data/Product/Tuple.md",
"Language/Row Types",
"Data/Sum/Either.md",
"Language/Functions.md",
"Language/Functions/Defining/Guard Clause.md",
"Language/Typeclasses.md",
"Language/Type Signature.md",
"Class/Monoid.md",
"Class/Semigroup.md",
"Class/Math/EuclideanRing.md",
"Class/Math/Semiring.md",
"Class/Math/DivisionRing.md",
"Class/Math/Ring.md",
"Class/Semiring.md",
"Class/Math",
"Class/Foldable.md",
"Terminology/Purity.md",
"Language/Expressions/do notation.md",
"Monads/Classes/Stack-safe recursion",
"Monads/Classes/Early Return",
"Monads/Classes/State",
"Monads/Classes/F",
"Monads/Classes/Error Handling",
"Classes/Math",
"Untitled 1.canvas",
"Untitled.canvas"
]

View File

@ -1,12 +0,0 @@
Generalizes [[Functor]] to functions with 2+ arguments
```haskell
apply ::
forall f a b
. Apply f
=> f (a -> b)
-> f a
-> f b
infixl apply as <*>
```

View File

@ -0,0 +1,52 @@
Alt is used most often as boolean OR on fallible [[Functor|functors]], but is technically whatever associative operation makes sense for the [[Data Structures|data]] type.
```haskell
class Functor f <= Alt f where
alt :: forall a. f a -> f a -> f a
```
### Examples
In [[Maybe]], Alt allows chainable defaults:
```haskell
Just 1 <|> Just 2
-- Just 1
Nothing <|> Just 1
-- Just 1
Nothing <|> Nothing
-- Nothing
Nothing <|> Nothing <|> Just 1
-- Just 1
```
In [[Either]], Alt works as a try/catch:
```haskell
Left "error!" <|> Right "it's ok i recovered"
-- Right "it's ok i recovered"
Right "i succeeded!" <|> Right "backup"
-- Right "i succeeded!"
Right unit <|> Left "uh oh!"
-- Right unit
Left "a" <|> Left "b"
-- Left "b"
```
> [!attention]
> Note that Alt in Either takes the last `Left` when all are `Left`!
In [[Array]], Alt is append:
```haskell
[] <|> [] -- []
["a"] <|> [] -- ["a"]
[] <|> ["a"] -- ["a"]
["a"] <|> ["b"] -- ["a", "b"]
["a"] <|> ["b", "c"] -- ["a", "b", "c"]
```

View File

@ -0,0 +1 @@
Doesn't have any class members, just requires that `f` in `Alternative f` must also be [[Plus]] and [[Alt]].

View File

@ -0,0 +1,39 @@
Extends [[Alt]] with an empty value:
```haskell
class Alt f <= Plus f where
empty :: forall a. f a
```
> [!info]
> Conceptually, this lives next to [[Applicative|pure]] in my mind; in [[Maybe]] for example `pure` and `empty` are aliases for `Just` and `Nothing`.
In [[Array]], `empty` is empty array `[]`. In [[Maybe]], `empty` is `Nothing`.
The most common place you'll see `empty` is when using [[MaybeT]] as an early return:
```haskell
logDebug :: String -> Effect Unit
logDebug msg = void $ runMaybeT do
env <- MaybeT $ Process.lookupEnv "NODE_ENV"
when (env /= "DEVELOPMENT") empty
lift $ Console.log msg
```
this is equivalent to:
```haskell
logDebug :: String -> Effect Unit
logDebug msg = do
menv <- Process.lookupEnv "NODE_ENV"
case menv of
Just env ->
if env == "DEVELOPMENT" then
Console.log msg
else
pure unit
Nothing -> pure unit
```
> [!info]
> Note that [guard](https://pursuit.purescript.org/packages/purescript-control/docs/Control.Alternative#v:guard) is a shorthand available for `when (..) empty`

View File

@ -0,0 +1,18 @@
Adds the `pure` [[Functions|function]] to [[Apply]], allowing arbitrary values to be wrapped in a [[Functor]].
```haskell
class Apply f <= Applicative f where
pure :: forall a. a -> f a
```
### Examples
`pure a` in various types:
type|equivalent to
---|---
[[Array]]|`[a]`
[[List]]|`Cons a`
[[Maybe]]|`Just a`
[[Either]]|`Right a`
[[Effect]]|`() => a`<sup><i>more or less</i></sup>
[[Aff]]|`Promise.resolve(a)`<sup><i>more or less</i></sup>

View File

@ -0,0 +1,79 @@
Generalizes [[Functor#map|map]] to [[Functions|functions]] with 2+ arguments; lifting functions `a -> b -> c` to `f a -> f b -> f c`
```haskell
class Functor f <= Apply f where
apply :: forall a b. f (a -> b) -> f a -> f b
infixl apply as <*>
```
> [!tip]
> Apply often replaces the pattern of "building towards a final result"
>
> Consider a function that [[Tuple|tuple]]s together its arguments
> ```haskell
> mk3Tuple a b c = a /\ b /\ c
> ```
>
> A common situation is wanting to build something like this 3-tuple from some components that are trapped in a context like [[Maybe]] or [[Either]], and we want to say "when all these things are ok, build it"; this is exactly what Apply lets us do:
>
> ```haskell
> maybeMk3Tuple :: Maybe a -> Maybe b -> Maybe c -> Maybe (a /\ b /\ c)
> maybeMk3Tuple ma mb mc = Just mk3Tuple <*> ma <*> mb <*> mc
>
> maybeMk3Tuple (Just 1) (Just 2) (Just 3)
> -- Just (1 /\ 2 /\ 3)
>
> maybeMk3Tuple (Just "a") (Just 3) (Nothing)
> -- Nothing
>
> maybeMk3Tuple Nothing Nothing Nothing
> -- Nothing
> ```
> [!tip]
> Obscure but occasionally usefully, Apply in collections lets us apply multiple functions to each element:
> ```haskell
> [(_ * 10), (_ * 20)] <*> [1, 2, 3]
> -- [10, 20, 20, 40, 30, 60]
>
> [identity, const ", "] <*> ["a", "b", "c"]
> -- ["a", ",", "b", ",", "c", ","]
> ```
### Examples
lift `(a + b) / c` to [[Maybe]]
```haskell
f :: Number -> Number -> Number
f a b c = (a + b) / c
mf :: Maybe Number -> Maybe Number -> Maybe Number
mf ma mb mc = pure f <*> ma <*> mb <*> mc
```
Build up a `Person` [[Record|record]] from Maybe fields; short-circuiting to `Nothing` if any fields are `Nothing`
```haskell
type PartialPerson =
{ name :: Maybe String
, email :: Maybe String
, password :: Maybe String
}
type Person =
{ name :: String
, email :: String
, password :: String
}
person :: PartialPerson -> Person
person
{ name: name'
, email: email'
, password: password'
} =
let
buildPerson name email password = {name, email, password}
in
Just buildPerson <*> name' <*> email' <*> password'
```

View File

@ -1,4 +1,3 @@
## What
[[Typeclasses|Typeclass]] defining the [[Functions|function]] `map`, [[Infix Operators|operators]] `<$>`, and `<#>`.
```haskell
@ -6,11 +5,21 @@ class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
```
## Why
Modify the data contained in a [[Data Structures|data structure]]
## map
For a [[Data Structures|data structure]] containing some data `a`, change the data using some function `a -> b`.
### Abstracts
- For every element in [[Collections|collection]] ...
> [!info]
> Another way of thinking of map is that it **lifts** a function of `a -> b` to `f a -> f b`:
> ```haskell
> addTwo :: Int -> Int
> addTwo = add 2
>
> maybeAddTwo :: Maybe Int -> Maybe Int
> maybeAddTwo = map addTwo
> ```
Replaces the patterns:
- Modify every element in [[Collections|collection]] ...
- When [[Maybe|nullable]] value is non-null ...
- When _(potentially async)_ [[Effect|IO]] resolves ...

View File

@ -1,6 +1,7 @@
|Operator|Description|Associativity|Precedence|Defined As|
|--|--|--|--|--|
|`<>`|append|right|5|[`Data.Semigroup.append`](https://pursuit.purescript.org/packages/purescript-prelude/docs/Data.Semigroup#v:(%3C%3E))|
|`/\`|Tuple constructor|right|6|[`Data.Tuple.Nested.Tuple`](https://pursuit.purescript.org/packages/purescript-tuples/docs/Data.Tuple.Nested#v:(%2F%5C))|
|`<$>`|map|||
|`<#>`|flipped map|||
|`<*>`|apply (map using function of 2+ arguments)|||

View File

View File

View File

View File

View File