Skip to content

Commit

Permalink
Complete the brief introduction of TypeApplications
Browse files Browse the repository at this point in the history
  • Loading branch information
igrep committed Sep 8, 2024
1 parent 5be601e commit 42ad6c5
Showing 1 changed file with 29 additions and 33 deletions.
62 changes: 29 additions & 33 deletions assets/19.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,53 +151,49 @@ ghci> :t map
map :: (a -> b) -> [a] -> [b]
```

`map`関数は👆の`:t`コマンドの結果の通り`a``b`という二つの型変数を使っています`TypeApplications`を使えばそれぞれの型変数を手動で代入することができます例えば次のように`map @Bool @String`と書くと型変数`a`に`Bool`型変数`b`に`String`を代入した`map`関数が出来上がります:
`map`関数は👆の`:t`コマンドの結果の通り`a``b`という二つの型変数を使っています`TypeApplications`を使えばそれぞれの型変数を手動で代入することができます例えば次のように`map @Bool @Integer`と書くと型変数`a`に`Bool`型変数`b`に`Integer`を代入した`map`関数が出来上がります:

```haskell
ghci> :t map @Bool @String
map @Bool @String :: (Bool -> String) -> [Bool] -> [String]
ghci> :t map @Bool @Integer
map @Bool @Integer :: (Bool -> Integer) -> [Bool] -> [Integer]
```

通常、この、型変数に具体的な型を代入する処理は型推論によってコンパイル時に自動で行われますが、`TypeApplications`を有効にすると、ユーザーが自ら制御できるようになるのです。

`TypeApplications`で作られた`map @Bool @String`は、`Bool`型のリストを受け取って、その各要素に`Bool -> String`関数を適用し、`String`型のリストを返す、専用の関数となっています。そのため、hoge
`TypeApplications`で作られた`map @Bool @Integer`は、`Bool`型のリストを受け取って、その各要素に`Bool -> Integer`関数を適用し、`Integer`型のリストを返す、専用の関数となっています。そのため、通常の`map`関数と異なり必ず`Bool -> Integer`型の関数を渡さなければなりません:

```
ghci> :t map @Bool
map @Bool :: (Bool -> b) -> [Bool] -> [b]
ghci> map @Bool length ["aaa", "bb", "cccc"]
```haskell
-- 引数の型が`Bool`ではなく`Integer`なのでエラー
ghci> :t map @Bool @Integer (+1)

<interactive>:8:11: error:
? Couldn't match type ‘Bool’ with ‘[a0]’
Expected type: Bool -> Int
Actual type: [a0] -> Int
? In the second argument of ‘map’, namely ‘length’
In the expression: map @Bool length ["aaa", "bb", "cccc"]
In an equation for ‘it’:
it = map @Bool length ["aaa", "bb", "cccc"]
<interactive>:1:21: error:
? Couldn't match type Bool with Integer
Expected: Bool -> Integer
Actual: Bool -> Bool
? In the third argument of map, namely (+ 1)
In the expression: map @Bool @Integer (+ 1)

<interactive>:8:19: error:
? Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
? In the expression: "aaa"
In the third argument of ‘map’, namely ‘["aaa", "bb", "cccc"]’
In the expression: map @Bool length ["aaa", "bb", "cccc"]
-- 戻り値の型が`Integer`ではなく`String`なのでエラー
ghci> :t map @Bool @Integer show

<interactive>:8:26: error:
? Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
? In the expression: "bb"
In the third argument of ‘map’, namely ‘["aaa", "bb", "cccc"]’
In the expression: map @Bool length ["aaa", "bb", "cccc"]
<interactive>:1:20: error:
? Couldn't match type [Char] with Integer
Expected: Bool -> Integer
Actual: Bool -> String
? In the third argument of map, namely show
In the expression: map @Bool @Integer show

<interactive>:8:32: error:
? Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
? In the expression: "cccc"
In the third argument of ‘map’, namely ‘["aaa", "bb", "cccc"]’
In the expression: map @Bool length ["aaa", "bb", "cccc"]
-- これはOK。if式を利用し、Bool型の値からInteger型の値を返す関数
ghci> :t map @Bool @Integer (\x -> if x then 1 else 0)
map @Bool @Integer (\x -> if x then 1 else 0)
:: [Bool] -> [Integer]
```

今回は、`Monad`のことを考えないために、`(>>)``m``TypeApplications``IO`に置き換えて見てみるのに使いましょう
このように`TypeApplications`を使うことで`map`関数が受け取る型変数に手動で具体的な型を代入することができるようになります

```
今回は`Monad`のことを考えないために`(>>)`の`m`を`TypeApplications`で`IO`に置き換えてみるのに使いましょう

```haskell
ghci> :t (>>) @IO
(>>) @IO :: IO a -> IO b -> IO b
```
Expand Down

0 comments on commit 42ad6c5

Please sign in to comment.