doc
This commit is contained in:
parent
9169968d89
commit
36a993eb96
12
exercise-purs/.gitignore
vendored
Normal file
12
exercise-purs/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
bower_components/
|
||||||
|
node_modules/
|
||||||
|
.pulp-cache/
|
||||||
|
output/
|
||||||
|
output-es/
|
||||||
|
generated-docs/
|
||||||
|
.psc-package/
|
||||||
|
.psc*
|
||||||
|
.purs*
|
||||||
|
.psa*
|
||||||
|
.spago
|
16
exercise-purs/spago.yaml
Normal file
16
exercise-purs/spago.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package:
|
||||||
|
dependencies:
|
||||||
|
- arrays
|
||||||
|
- console
|
||||||
|
- effect
|
||||||
|
- ordered-collections
|
||||||
|
- parsing
|
||||||
|
- prelude
|
||||||
|
name: foo
|
||||||
|
test:
|
||||||
|
dependencies: []
|
||||||
|
main: Test.Main
|
||||||
|
workspace:
|
||||||
|
extra_packages: {}
|
||||||
|
package_set:
|
||||||
|
registry: 42.2.1
|
89
exercise-purs/src/Data.CSV.purs
Normal file
89
exercise-purs/src/Data.CSV.purs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
module Data.CSV where
|
||||||
|
|
||||||
|
import Prelude hiding (between)
|
||||||
|
|
||||||
|
import Control.Alt ((<|>))
|
||||||
|
import Data.Array (some)
|
||||||
|
import Data.Either (Either)
|
||||||
|
import Data.Foldable (all)
|
||||||
|
import Data.List (List(..))
|
||||||
|
import Data.List.NonEmpty (NonEmptyList, zip)
|
||||||
|
import Data.Map as M
|
||||||
|
import Data.String.CodeUnits (fromCharArray, toCharArray, singleton)
|
||||||
|
import Parsing (ParseError, Parser, runParser)
|
||||||
|
import Parsing.Combinators (sepEndBy, sepBy1, between)
|
||||||
|
import Parsing.String (eof, satisfy, string)
|
||||||
|
|
||||||
|
type P a = Parser String a
|
||||||
|
|
||||||
|
type Parsers a =
|
||||||
|
{
|
||||||
|
quoted :: (P a -> P a),
|
||||||
|
chars :: P String,
|
||||||
|
qchars :: P String,
|
||||||
|
field :: P String,
|
||||||
|
row :: P (NonEmptyList String),
|
||||||
|
file :: P (List (NonEmptyList String)),
|
||||||
|
fileHeaded :: P (List (M.Map String String))
|
||||||
|
}
|
||||||
|
|
||||||
|
makeQuoted :: forall a. String -> (P a -> P a)
|
||||||
|
makeQuoted q = between (string q) (string q)
|
||||||
|
|
||||||
|
makeChars :: String -> P String
|
||||||
|
makeChars xs = do
|
||||||
|
fromCharArray <$> some char
|
||||||
|
where
|
||||||
|
char = satisfy $ excluded xs
|
||||||
|
excluded ys = \x -> all identity $ terms ys <*> [x]
|
||||||
|
terms ys = map (/=) $ toCharArray ys
|
||||||
|
|
||||||
|
makeQchars :: Char -> P String
|
||||||
|
makeQchars c = fromCharArray <$> some (qchar <|> escapedQuote)
|
||||||
|
where
|
||||||
|
escapedQuote :: P Char
|
||||||
|
escapedQuote = (string $ (singleton c <> singleton c)) $> c
|
||||||
|
qchar = satisfy (\c' -> c' /= c)
|
||||||
|
|
||||||
|
makeField :: (P String -> P String) -> P String -> P String -> P String
|
||||||
|
makeField qoutes qoutedChars purechars = qoutes qoutedChars <|> purechars <|> string ""
|
||||||
|
|
||||||
|
makeRow :: String -> P String -> P (NonEmptyList String)
|
||||||
|
makeRow s f = f `sepBy1` string s
|
||||||
|
|
||||||
|
makeFile :: String -> P (NonEmptyList String) -> P (List (NonEmptyList String))
|
||||||
|
makeFile s r = r `sepEndBy` string s <* eof
|
||||||
|
|
||||||
|
makeFileHeaded :: P (List (NonEmptyList String)) -> P (List (M.Map String String))
|
||||||
|
makeFileHeaded file = do
|
||||||
|
f <- file
|
||||||
|
pure $ case f of
|
||||||
|
Nil -> Nil
|
||||||
|
Cons header rows -> mkRow header <$> rows
|
||||||
|
where
|
||||||
|
mkRow header row' = M.fromFoldable $ zip header row'
|
||||||
|
|
||||||
|
makeParsers :: Char -> String -> String -> Parsers String
|
||||||
|
makeParsers quote seperator eol = do
|
||||||
|
let quoted' = makeQuoted $ singleton quote
|
||||||
|
let chars' = makeChars $ (singleton quote) <> seperator <> eol
|
||||||
|
let qchars' = makeQchars quote
|
||||||
|
let field' = makeField quoted' qchars' chars'
|
||||||
|
let row' = makeRow seperator field'
|
||||||
|
let file' = makeFile eol row'
|
||||||
|
let fileHeaded' = makeFileHeaded file'
|
||||||
|
{
|
||||||
|
quoted: quoted',
|
||||||
|
chars: chars',
|
||||||
|
qchars: qchars',
|
||||||
|
field: field',
|
||||||
|
row: row',
|
||||||
|
file: file',
|
||||||
|
fileHeaded: fileHeaded'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultParsers :: Parsers String
|
||||||
|
defaultParsers = makeParsers '"' "," "\n"
|
||||||
|
|
||||||
|
parse :: String -> Either ParseError (List (NonEmptyList String))
|
||||||
|
parse = flip runParser $ defaultParsers.file
|
11
exercise-purs/src/Main.purs
Normal file
11
exercise-purs/src/Main.purs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Console (log)
|
||||||
|
|
||||||
|
main :: Effect Unit
|
||||||
|
main = do
|
||||||
|
log "🍝"
|
||||||
|
|
12
exercise-purs/test/Test/Main.purs
Normal file
12
exercise-purs/test/Test/Main.purs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module Test.Main where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Class.Console (log)
|
||||||
|
|
||||||
|
main :: Effect Unit
|
||||||
|
main = do
|
||||||
|
log "🍕"
|
||||||
|
log "You should add some tests."
|
||||||
|
|
8
exercise-rs/Cargo.toml
Normal file
8
exercise-rs/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "exercise-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
3
exercise-rs/src/main.rs
Normal file
3
exercise-rs/src/main.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
129
readme.md
129
readme.md
@ -1,10 +1,21 @@
|
|||||||
# thunderstrike.ai intern resources
|
# thunderstrike.ai intern resources
|
||||||
|
|
||||||
|
## contents
|
||||||
|
* [rust](#rust)
|
||||||
|
* [in brief](#rust-in-brief)
|
||||||
|
* [purescript](#purescript)
|
||||||
|
* [in brief](#purescript-in-brief)
|
||||||
|
* [example - frontend app](#purescript-example-frontend-app)
|
||||||
|
* [optional exercise](#exercise)
|
||||||
|
* [setup](#exercise-setup)
|
||||||
|
* [task](#exercise-task)
|
||||||
|
* [further reading](#further-reading)
|
||||||
|
|
||||||
## rust
|
## rust
|
||||||
**Rust** is a strongly-typed <a href="https://en.wikipedia.org/wiki/Type_safety"><sup>[type safety]</sup></a>
|
**Rust** is a strongly-typed <a href="https://en.wikipedia.org/wiki/Type_safety"><sup>[type safety]</sup></a>
|
||||||
systems programming language <a href="https://en.wikipedia.org/wiki/System_programming_language"><sup>[systems programming language]</sup></a>.
|
systems programming language <a href="https://en.wikipedia.org/wiki/System_programming_language"><sup>[systems programming language]</sup></a>.
|
||||||
|
|
||||||
### In brief
|
### Rust in brief
|
||||||
<ul>
|
<ul>
|
||||||
<li>Error handling is done with a special type that represents "the `Result` of this may be an error"</li>
|
<li>Error handling is done with a special type that represents "the `Result` of this may be an error"</li>
|
||||||
<li>Null values are represented by special type that represents "this value is `Option`al"</li>
|
<li>Null values are represented by special type that represents "this value is `Option`al"</li>
|
||||||
@ -16,7 +27,7 @@ systems programming language <a href="https://en.wikipedia.org/wiki/System_progr
|
|||||||
purely functional <a href="https://en.wikipedia.org/wiki/Purely_functional_programming"><sup>[purely functional]</sup></a>
|
purely functional <a href="https://en.wikipedia.org/wiki/Purely_functional_programming"><sup>[purely functional]</sup></a>
|
||||||
programming language that compiles to javascript (like typescript).
|
programming language that compiles to javascript (like typescript).
|
||||||
|
|
||||||
### In brief
|
### Purescript in brief
|
||||||
<ul>
|
<ul>
|
||||||
<li>Error handling is done with a special type that represents "`Either` it succeeded or failed"</li>
|
<li>Error handling is done with a special type that represents "`Either` it succeeded or failed"</li>
|
||||||
<li>Null values are represented by special type that represents "`Maybe` it's present or not"</li>
|
<li>Null values are represented by special type that represents "`Maybe` it's present or not"</li>
|
||||||
@ -29,7 +40,7 @@ programming language that compiles to javascript (like typescript).
|
|||||||
<li>interacting with raw javascript is relatively painless</li>
|
<li>interacting with raw javascript is relatively painless</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
### Motivating example: React vs Halogen
|
### Purescript Example - Frontend App
|
||||||
You don't have to understand exactly how these examples work,
|
You don't have to understand exactly how these examples work,
|
||||||
I'm providing them simply for you to glance over and get a feeling
|
I'm providing them simply for you to glance over and get a feeling
|
||||||
for reading typescript/javascript vs purescript.
|
for reading typescript/javascript vs purescript.
|
||||||
@ -115,9 +126,121 @@ app = mkComponent
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## Exercise
|
||||||
|
This is an optional code exercise for you to use if you have extra
|
||||||
|
time and would like a somewhat guided foray into one or both of the languages
|
||||||
|
mentioned here.
|
||||||
|
|
||||||
|
### Exercise - Setup
|
||||||
|
#### Windows
|
||||||
|
This guide assumes you are using linux or macos.
|
||||||
|
On windows, install an ubuntu virtual machine on WSL2 using this guide: https://learn.microsoft.com/en-us/windows/wsl/install
|
||||||
|
|
||||||
|
After installing, run the following:
|
||||||
|
```sh
|
||||||
|
apt-get update -y
|
||||||
|
apt-get upgrade -y
|
||||||
|
apt-get install -y wget curl git openssl zsh
|
||||||
|
```
|
||||||
|
|
||||||
|
If using Visual Studio Code, this guide will help you configure VSCode to run in WSL instead of Windows: https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode
|
||||||
|
|
||||||
|
#### VSCode
|
||||||
|
* [rust](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
|
||||||
|
* [purescript](https://marketplace.visualstudio.com/items?itemName=nwolverson.ide-purescript)
|
||||||
|
|
||||||
|
#### asdf
|
||||||
|
For tooling, I recommend using [asdf](asdf-vm.com)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
|
||||||
|
echo 'source "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
|
||||||
|
echo 'source "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
|
||||||
|
echo '[ -s "~/.bun/_bun" ] && source "~/.bun/_bun"' >> ~/.bashrc
|
||||||
|
echo 'export BUN_INSTALL="~/.bun"' >> ~/.bashrc
|
||||||
|
echo 'export PATH=$PATH:$HOME/.bun/bin' >> ~/.bashrc
|
||||||
|
|
||||||
|
asdf plugin add rust
|
||||||
|
asdf plugin add bun
|
||||||
|
asdf plugin add purescript
|
||||||
|
|
||||||
|
asdf install rust latest
|
||||||
|
asdf install bun latest
|
||||||
|
asdf install purescript latest
|
||||||
|
|
||||||
|
asdf global rust latest
|
||||||
|
asdf global bun latest
|
||||||
|
asdf global purescript latest
|
||||||
|
|
||||||
|
bun install --global spago@next
|
||||||
|
|
||||||
|
cargo --version
|
||||||
|
echo -n "bun " && bun --version
|
||||||
|
echo -n "purescript " && purs --version
|
||||||
|
echo -n "spago " && spago --version
|
||||||
|
# cargo 1.70.0
|
||||||
|
# bun 1.0.3
|
||||||
|
# purescript 0.15.11-3
|
||||||
|
# spago 0.93.14
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Clone this repo
|
||||||
|
```sh
|
||||||
|
git clone https://git.orionkindel.com/orion/intern-resources.git
|
||||||
|
|
||||||
|
cd intern-resources/example-rs
|
||||||
|
cargo build
|
||||||
|
cargo run
|
||||||
|
|
||||||
|
cd ../example-purs
|
||||||
|
spago build
|
||||||
|
spago run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exercise - Task
|
||||||
|
In either purescript or rust, write a program that operates on CSV data and transforms it into JSON.
|
||||||
|
|
||||||
|
#### Purescript Instructions
|
||||||
|
* use the provided template `./exercise-purs/`
|
||||||
|
* use the provided CSV parser `./exercise-purs/src/Data.CSV.purs`
|
||||||
|
* modify `./exercise-purs/src/Main.purs` to read a csv file and print it as JSON to the terminal
|
||||||
|
|
||||||
|
_hints:_
|
||||||
|
* [`Node.FS.Sync.readFile`](https://pursuit.purescript.org/packages/purescript-node-fs/9.1.0/docs/Node.FS.Sync#v:readFile)
|
||||||
|
* [`Simple.JSON.writeJSON`](https://pursuit.purescript.org/packages/purescript-simple-json/9.0.0/docs/Simple.JSON#v:writeJSON)
|
||||||
|
|
||||||
|
#### Rust Instructions
|
||||||
|
* use the provided template `./exercise-rs/`
|
||||||
|
* use the [`csv`](https://docs.rs/csv/latest/csv/) crate to parse csvs
|
||||||
|
* modify `./exercise-rs/src/main.rs` to read a csv file and print it as JSON to the terminal
|
||||||
|
|
||||||
|
_hints:_
|
||||||
|
* [`csv`](https://docs.rs/csv/latest/csv/)
|
||||||
|
* [`serde_json`](https://docs.rs/csv/latest/serde-json/)
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
The input
|
||||||
|
```csv
|
||||||
|
Title,Salary,Name
|
||||||
|
CEO,100000,Jack
|
||||||
|
CTO,100000,Bryan
|
||||||
|
Engineer,80000,Jennifer
|
||||||
|
```
|
||||||
|
|
||||||
|
Should output
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"Title": "CEO", "Salary": "100000", "Name": "Jack"},
|
||||||
|
{"Title": "CTO", "Salary": "100000", "Name": "Bryan"},
|
||||||
|
{"Title": "Engineer", "Salary": "80000", "Name": "Jennifer"},
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
## Further reading
|
## Further reading
|
||||||
* [purescript website](https://www.purescript.org/)
|
* [purescript website](https://www.purescript.org/)
|
||||||
* [purescript by example (free online book)](https://book.purescript.org/)
|
* [purescript by example (free online book)](https://book.purescript.org/)
|
||||||
* [purescript in depth (free online book)](https://leanpub.com/purescript/read)
|
* [purescript in depth (free online book)](https://leanpub.com/purescript/read)
|
||||||
|
* [purescript halogen docs](https://purescript-halogen.github.io/purescript-halogen/)
|
||||||
|
* [purescript halogen implementation of the realworld project](https://github.com/thomashoneyman/purescript-halogen-realworld)
|
||||||
* [rust website](https://www.rust-lang.org/)
|
* [rust website](https://www.rust-lang.org/)
|
||||||
* [rust book (free online book)](https://doc.rust-lang.org/book/)
|
* [rust book (free online book)](https://doc.rust-lang.org/book/)
|
||||||
|
Loading…
Reference in New Issue
Block a user