An open API service indexing awesome lists of open source software.

https://github.com/ivan-kleshnin/random-mess


https://github.com/ivan-kleshnin/random-mess

Last synced: 7 months ago
JSON representation

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))
```