为什么Haskell可以在此函数中推导出[]类型

Sil*_*ili 2 haskell types

rho x = map (((flip mod) x).(\a -> a^2-1)) (rho x)
Run Code Online (Sandbox Code Playgroud)

此函数将生成无限列表.我在GHCi中测试过,功能类型是

*Main> :t rho
rho :: Integral b => b -> [b]
Run Code Online (Sandbox Code Playgroud)

如果我定义这样的函数

fun x = ((flip mod) x).(\a -> a^2-1)
Run Code Online (Sandbox Code Playgroud)

类型是

*Main> :t fun
fun :: Integral c => c -> c -> c
Run Code Online (Sandbox Code Playgroud)

我的问题是,Haskell如何将函数类型推导为b - > [b]?我们在这个函数中没有任何[]类型的数据.谢谢!

pat*_*pat 14

map 有以下类型:

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

因此,我们可以推断出参数的类型map:

(((flip mod) x).(\a -> a^2-1)) :: (a -> b)
(rho x) :: [a]
Run Code Online (Sandbox Code Playgroud)

但结果map也是结果rho x,所以:

(rho x) :: [b]
Run Code Online (Sandbox Code Playgroud)

这意味着ab属于同一类型,所以:

rho :: ? -> [b]
Run Code Online (Sandbox Code Playgroud)

如果我们检查映射函数,并使其x自由,我们找到类型:

\x -> ((flip mod) x).(\a -> a^2-1) :: Integral b => b -> (b -> b)
Run Code Online (Sandbox Code Playgroud)

Integral b => b给我们的类型x,以及(b -> b)与复合函数的类型相结合,让我们知道这b是一样的前一个.

rho :: Integral b => b -> [b]
Run Code Online (Sandbox Code Playgroud)


Kaz*_*Kaz 6

(rho x)必须返回一个列表,因为它被传递给map列表元素的类型可以从映射中发生的内容推断出来.