На лоре тут продолжается лиспосрач.
Интересная программка на хаскеле.
Тут мы забыли написать ```x``` в конце. Бывает хули.
```
$ cat Test.hs
module Test
where
strlen x = length
```
Модуль компилируется, все ок, потому что в хаскеле подефолту каррирование и тайпинференс.
```
$ ghc Test.hs
[1 of 1] Compiling Test ( Test.hs, Test.o )
```
Здесь обычное использование бажного strlen, который мы написали.
```
$ cat Main.hs
import Test
main = do
putStrLn "Please enter a word"
num <- getLine
let size = strlen num
putStrLn $ "The size of your string is: " ++ show size ++ "!"
```
Компилируем его и получаем клевые сообщения об ошибках!
```
$ ghc Main.hs
[2 of 2] Compiling Main ( Main.hs, Main.o )
Main.hs:7:48:
No instance for (Show ([a0] -> Int)) arising from a use of `show'
Possible fix: add an instance declaration for (Show ([a0] -> Int))
In the first argument of `(++)', namely `show size'
In the second argument of `(++)', namely `show size ++ "!"'
In the second argument of `($)', namely
`"The size of your string is: " ++ show size ++ "!"'
```
В чем тут проблема? В том, что тайпчекер не заставил нас написать аннотацию для top-level функции strlen,
а вывел типы из определения функции, причем типы вывел не те, которые мы хотели.
То есть, вместо того чтобы сказать программисту, чтобы он предоставил сигнатуру функции и сказал чего хочет, компилятор вывел типы и зафейлился уже в другом месте.
В хаскеле есть флаг чтобы запретить декларирование top-level функций без сигнатурок?
tldr: с type inference надо быть аккуратным.