手动派生类型`(.)(foldr(++))(map(:))`

Fof*_*Fof 2 haskell types unification ghci

我试图推导出类型 (.) (foldr(++)) (map (:))

我首先推导出类型 foldr (++)

foldr :: (a1 -> b1 -> b1) -> b1 -> [a1] -> b1
(++)  :: [a2] -> [a2] -> [a2]

a1 ~ [a2]
b1 ~ [a2]
b1 ~ [a2]
Run Code Online (Sandbox Code Playgroud)

所以

foldr (++) :: [a2] -> [[a2]] -> [a2] ~ [a] -> [[a]] -> [a]
Run Code Online (Sandbox Code Playgroud)

然后我推导出类型 map (:)

map :: (a1 -> b1) -> [a1] -> [b1]
(:) :: a2 -> [a2] -> [a2]

a1 ~ a2
b1 ~ [a2] -> [a2]
Run Code Online (Sandbox Code Playgroud)

所以

map (:) :: [a2] -> [[a2] -> [a2]] ~ [a] -> [[a] -> [a]]
Run Code Online (Sandbox Code Playgroud)

最后的类型 (.) (foldr(++)) (map (:))

(.) :: (b1 -> c1) -> (a1 -> b1) -> a1 -> c1
map (:) :: [a2] -> [[a2] -> [a2]]
foldr (++) :: [a3] -> [[a3]] -> [a3]

b1 ~ [a2]
c1 ~ [[a2] -> [a2]]
a1 ~ [a3]
b1 ~ [[a3]] -> [a3]
Run Code Online (Sandbox Code Playgroud)

所以我明白了

(.) (foldr(++)) (map (:)) :: a1 -> c1 ~ [a3] ->  [[a2] -> [a2]]
Run Code Online (Sandbox Code Playgroud)

但如果我问GHCi :t (.) (foldr(++)) (map (:))我得到了(.) (foldr(++)) (map (:)) :: [a] -> [[[a] -> [a]]] -> [[a] -> [a]]

哪个与我的结果不同,是否有任何帮助来得出相同的结果?

谢谢,
塞巴斯蒂安.

Tox*_*ris 9

在最后一步中,你将论点混为一谈.你统一b1 -> c1了类型map (:),但你应该用它的类型统一它foldr (++).

更一般地说,您可能想学习如何自己调试这些复杂的计算.最后进行健全性检查是很好的(在这种情况下,通过使用ghci检查结果).如果完整性检查不起作用,那么下一步就是说出或写下每个步骤是什么以及为什么要这样做.在这种情况下,你会说"然后我统一b1 -> c1map (:)因为... 的类型",你会发现这个错误,因为没有理由这样做.

也许橡皮鸭调试适合你,在那里你向橡皮鸭解释你的代码,并通过解释,你看到代码有什么问题..