https://github.com/ivan-kleshnin/random-mess
https://github.com/ivan-kleshnin/random-mess
Last synced: 7 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/ivan-kleshnin/random-mess
- Owner: ivan-kleshnin
- Created: 2016-02-29T18:16:31.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2016-02-29T20:52:28.000Z (over 9 years ago)
- Last Synced: 2025-02-01T22:12:52.330Z (8 months ago)
- Size: 6.84 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# From JS to Haskell and back again
Sample backend program to calculate and output file length (in chars).
File path is passed as a first CLI argument.---
## JS to Haskell
#### 1. Promises :suspect:
```js
main = getArgs().then(compose(readFile, head)).then(compose(print, length))
```Legend
```
getArgs ~ get CLI arguments
compose ~ Ramda.compose
head ~ xs[0] equivalent
readFile ~ read file by path
print ~ ::console.log
length ~ ::length
```#### 2. Replace `then` with `chain`
```js
// Bad news: `then` conflates `map` and `flatMap` behaviors...
main = getArgs().then(compose(readFile, head)).then(compose(print, length))// it should be
main = getArgs().flatMap(compose(readFile, head)).flatMap(compose(print, length))// or
main = getArgs().chain(compose(readFile, head)).chain(compose(print, length))
```#### 3. Replace methods with functions
```js
main = chain(compose(print, length), chain(compose(readFile, head), getArgs()))
```#### 4. Apply Haskell grammar
```hs
main = chain (print . length) (chain (readFile . head) getArgs)
```#### 5. Replace `chain` with `>>=` operator
```hs
main = (>>=) (print . length) ((>>=) (readFile . head) getArgs) -- wrong argument order
```#### 6. Fix argument order for `>>=` operator
```hs
main = (>>=) ((>>=) getArgs (readFile . head)) (print . length)
```#### 7. Change order to normal for operators
```hs
main = getArgs >>= (readFile . head) >>= (print . length)
```Hint: `(+) 1 2 <=> 1 + 2`
#### 8. Remove parens
```hs
main = getArgs >>= readFile . head >>= print . length
```---
```
$ echo "import System.Environment; import Control.Monad; main = getArgs >>= readFile . head >>= print . length" > sample.hs
$ echo "pwned" > test.txt
$ runhaskell sample.hs test.txt
5
```---
## Haskell to JS
#### 1. Monads :goberserk:
```hs
main = getArgs >>= readFile . head >>= print . length
```#### 2. Add parens
```js
main = getArgs >>= (readFile . head) >>= (print . length)
```#### 3. Change order to normal for operators
```js
main = (>>=) ((>>=) getArgs (readFile . head)) (print . length)
```Hint: `1 + 2 <=> (+) 1 2`
#### 4. Reverse argument order
```hs
main = (>>=) (print . length) ((>>=) (readFile . head) getArgs) -- wrong argument order
```#### 5. Replace `>>=` operator with `chain`
```hs
main = chain (print . length) (chain (readFile . head) getArgs)
```#### 6. Apply JS grammar
```js
main = chain(compose(print, length), chain(compose(readFile, head), getArgs()))
```#### 7. Replace functions with methods
```hs
main = getArgs().chain(compose(readFile, head)).chain(compose(print, length))
```#### 8. Replace `chain` with `then` (`flatMap`)
```js
main = getArgs().then(compose(readFile, head)).then(compose(print, length))
```