# Line

## Curry Function

Curry Function是個「將一個接受 n 個參數的 function，轉變成 n 個只接受一個參數的 function」的過程，JavaScript的Array就是經典的Curry Function表現，範例如下：

```javascript
let boys = ['boy', 'girl'].concat(['boy', 'girl']).filter(s => s === 'boy')
```

{% hint style="info" %}
但Packhouse的Curry實現完全不是這樣 😰。
{% endhint %}

## Property

Install、Request都是針對`input`的[Tool Property](https://packhouse-doc.metalsheep.com/the-instance/tool#property)，對於執行Line的驗證。

而Response是針對`output`的驗證。

{% hint style="info" %}
Install的行為在每次呼叫時都會執行，對Line來說每一次都是新的開始。
{% endhint %}

```javascript
let line = {
    input: 'function',
    output: 'function',
    layout: 'tools',
    install: 'function',
    request: 'array',
    response: 'string'
}
```

## How To Use

為了擁有對付高度複雜性的功能，Line的定義並不輕鬆，Store是Line的主要共享狀態物件。

> 每次執行時Store都會是一個全新的對象，Tool則會永久保持最後設定的狀態。

{% hint style="info" %}
下列範例會看見只有在`output`時才真正回傳結果，而其他的動作代表`next`的行為。
{% endhint %}

```javascript
const group = {
    tools: {
        sum: {
            handler: (self, v1, v2) => self.success(v1, v2)
        }
    },
    lines: {
        math: {
            request: ['number'],
            response: 'number',
            install({ include }) {
                include('sum').tool('sum')
            },
            input(self, value) {
                self.store.value = value
                self.success()
            },
            output(self) {
                self.success(self.store.value)
            },
            layout: {
                add: {
                    request: ['number'],
                    handler(self, value) {
                        self.tool('sum')
                            .action((error, result) => {
                                self.store.value = result
                                self.success()
                            })
                    }
                },
                double: {
                    handler(self) {
                        self.store.value *= 2
                        self.success()
                    }
                }
            }
        }
    }
}

packhouse.addGroup('math', () => {
    return {
        data: group
    }
})
```

## Invoke

Line不存在noGood、always等[Pre-Invoke](https://packhouse-doc.metalsheep.com/the-instance/group/broken-reference)行為，也必須丟入一個初始值觸發`input`，相對的並不需要在最後中Invoke行為中給予任何參數，詳情請見[Invoke](https://packhouse-doc.metalsheep.com/the-instance/invoke)。

```javascript
packhouse
    .line('math/math')(10)
    .add(5)
    .add(10)
    .double()
    .action((error, result) => {
        console.log(result) // 50
    })
```
