haskell - 类型正确的功能可以不适用吗? ( haskell )

标签 haskell type-inference

我有一个函数foo = \f x -> let c = \y -> x in f c我已经推断出要找到的类型:
\forall a,b,r. ((b -> a) -> r) -> a -> r .

GHCI 确认此类型:foo :: ((p1 -> p2) -> t) -> p2 -> t
但是,我找不到满足这些参数的适用函数,例如 foo评估。

我尝试了以下功能但没有成功:

bu :: Num a => ([Char] -> a) -> a
bu x = (x "hello") * 2 

ba :: (Fractional a1, Foldable t) => t a2 -> a1
ba x = (fromIntegral (length x) ) / 2

另一种尝试是选择以下功能:
bu :: Num a => ([Char] -> a) -> a -> a
bu x = (+ ((x "hello") * 2))

ba :: (Fractional a1, Foldable t) => t a2 -> a1
ba x = (fromIntegral (length x) ) / 2

现在我可以调用(bu ba) 4并得到正确的结果。

我明白为什么那些不起作用。
问题似乎是在第一次争论中 (p1 -> p2) -> t) , t需要是一个接受参数 p2 的函数.但是,一旦我们这样做,该函数的类型就会更改为 (a -> a)并且不能再被 foo 正确使用。

这个练习让我想到了这个问题;具有正确类型的功能可以不适用吗?
我的直觉使我相信这是错误的,并且任何具有有效类型的函数都存在适​​用的输入。有证据吗?

最佳答案

这是一个简单的证明,证明函数可能不适用(不考虑底部)

data Never = Never Never

justTryIt :: Never -> ()
justTryIt _ = ()

但是您的功能适用

main = print $ foo (\c -> c ()) 3

那么那个 lambda 的类型是什么?

g :: (() -> a) -> a
g = \c -> c ()

重点是您不需要以下功能

g :: (a -> b) -> c

这是无人居住的(iGnOrInG 底部)。类型签名只是说您可以采用一个函数,其中所有 3 个类型(forall a b c.)都可以变化。 IE 这同样适用

g :: (Int -> String) -> Bool
g f = null $ f 3

main = print $ foo g "so concrete"

关于haskell - 类型正确的功能可以不适用吗? ( haskell ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60016363/

相关文章:

haskell - 实例化类型的幺半群

haskell - Yesod数据库迁移循环

F# 类型推断问题与 linq 和可能的 Entity Framework

C# 类型推断 : fails where it shouldn't?

f# - FSharp 和向上转换到接口(interface)似乎是多余的

haskell - Haskell 中的 const 函数声明

list - 如何从列表中获取得分最高的项目

parsing - Haskell - Parsec 与状态

typescript - 使用参数或泛型来约束另一个参数的类型?

f# - 将 OCaml 转换为 F# : Differences between typing and type inference