2.9 KiB
2.9 KiB
thunderstrike.ai intern resources
purescript
Purescript is a strongly-typed [type safety] purely functional [purely functional] programming language that compiles to javascript (like typescript).
In brief
- effectful code [side effect] is isolated from non-effectful code. This makes programs much more consistent to run and reason about.
- everything is an expression
- interacting with raw javascript is relatively painless
Motivating example: React vs Halogen
this frontend app:
- renders
"Loading..."
until either data or error - fetches data from a server
- if ok, render items in a list. if error, render error span at the bottom of the page.
React (click to expand)
type Item = {id: string, title: string, description: string}
export const App: () => React.Node = () => {
const [items, setItems] = React.useState<Array<Item> | undefined>(undefined)
const [error, setError] = React.useState<Error | undefined>(undefined)
React.useEffect(() => {
fetch('/api/item')
.then(rep => rep.json<Array<Item>>())
.then(items => setItems(items))
.catch(e => setError(e))
}, [])
return error !== undefined
? (<p class="error">{error.message}</p>)
: items === undefined
? (<p>Loading...</p>)
: items.map(item => {
return (
<div key={item.id}>
<p>{item.title}</p>
<span class="small">
{item.description}
</span>
</div>
)
})
}
Purescript Halogen (click to expand)
type Item = { id :: String
, title :: String
, description :: String
}
data State
= StateEmpty
| StateErrored Error
| StateGotItems (Array Item)
data Action = ActionInit
renderItem item =
div [] [ p [] [text item.title]
, span
[className "small"]
[text item.description]
]
renderApp StateEmpty = p [] [text "Loading..."]
renderApp (StateErrored e) = p [className "error"] [text (message e)]
renderApp (StateGotItems items) = map renderItem items
action ActionInit = do
response <- fetch (URL "/api/item") {method: Get}
jsonString <- text response
itemsOrError <- readJSON jsonString
case itemsOrError of
Right items -> put (StateGotItems items)
Left error -> put (StateErrored error)
app = mkComponent
{ initialState: StateEmpty
, render: renderApp
, eval:
mkEval ( defaultEval { handleAction = action
, initialize: Just ActionInit
}
)
}