类型为a的函数 - > b在哈斯克尔?

时间:2016-05-26 20:26:22

标签: haskell types type-inference unification

Haskell中是否有任何类型为a -> b的函数?这意味着,是否可以编写一个f :: a -> b的函数?我不认为这样的函数存在的原因如下:假设我们发现f f :: a -> bf 2会产生什么?类型b的值,但是什么是b,因为Haskell不能从我给出的参数中推断(我认为)它?它是否正确?否则,你能给我一个这样的功能的例子吗?

4 个答案:

答案 0 :(得分:7)

禁止<(底值 - undefined等),这总是可行但从不有用,确实没有这样的功能。这是我们从多态类型签名中获得的所谓row-activated signal of the GtkTreeView object的最简单实例之一。

你已经在正确的轨道上直截了当地解释了为什么这是不可能的,尽管它最终会消失。是的,您可以考虑f (5 :: Int)。问题是编译器“无法推断”b将是什么 - 对于许多实际功能而言,情况就是如此。

fromIntegral :: (Num b, Integral a) => a -> b

非常有意义; b将从使用fromIntegral x的环境中推断出。例如,我可能会写

average :: [Double] -> Double
average l = sum l / fromIntegral (length l)

在这种情况下,length l :: a具有固定类型IntfromIntegral (length l) :: b必须具有适合环境的固定类型Double,并且与大多数其他语言不同类型推断,来自环境的信息可以用基于Hindley-Milner的语言获得。

不,f :: a -> b的问题在于您可以将ab实例化为任何类型的荒谬组合,而不仅仅是不同的数字类型。因为f是无约束的多态的,所以它必须能够将任何类型转换为任何其他类型

特别是,它可以转换为空类型 free theorems

evil :: Int -> Void
evil = f

然后我可以

muahar :: Void
muahar = f 0

但是,通过Void的构造,不能成为这种类型的值(除了⊥,你可以在没有崩溃或无限循环的情况下进行评估)。 / p>

<小时/> 应该注意的是,这是某些标准不是计算平均值的非常好的方法。

答案 1 :(得分:2)

为了实施f :: a -> b,这意味着f必须能够返回任何可能的类型。即使是今天不存在的类型,但有些人可以在十年内定义&#39;时间。如果没有某种反射功能,那显然是不可能的。

嗯......&#34;不可能&#34;是一个大词......正如其他答案所指出的那样,排除底部是不可能的。换句话说,f永远不能返回类型为b的值。 可以抛出异常,或永远循环。但(可以说)这些事情都不是真的&#34;返回一个价值&#34;。

f1 :: a -> b
f1 = error "f1"

f2 :: a -> b
f2 s = error "f2"

f3 :: a -> b
f3 x = f3 x

这些功能都略有不同,它们都编译得很好。当然,他们都没用!是的,没有有用的函数,类型为a -> b

如果你想分裂头发:

  • f1抛出异常。
  • f1 'x'抛出异常。
  • f2是一个看起来很正常的功能。
  • f2 'x'抛出异常。
  • f3是一个看起来很正常的功能。
  • f3 'x'不会抛出异常,但它会永远循环,因此它实际上从未返回任何内容。

基本上你看到的任何函数返回&#34;任何类型&#34;是一个永远不会实际返回的函数。我们可以在不寻常的单子中看到这一点。例如:

f4 :: a -> Maybe b

完全可能实现此功能,而不会抛出异常或永远循环。

f4 x = Nothing

同样,我们实际上并没有返回一个b。我们也可以这样做

f5 :: a -> [b]
f5 x = []

f6 :: a -> Either String b
f6 x = Left "Not here"

f7 :: a -> Parser b
f7 x = fail "Not here"

答案 2 :(得分:1)

我认为,只有一个,但它有点作弊:

> let f _ = undefined
> :t f
f:: t -> t1

这只是因为底部被认为是每种类型的值。

答案 3 :(得分:0)

  

...但是什么是Containers with Aggregation,因为Haskell不能从我给出的论据中推断它?

根据上下文,Haskell可以推断出返回类型;说:

b

然后,

{-# LANGUAGE MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-}

class Cast a b where
    cast :: a -> b

instance Cast a a where
    cast = id

instance Cast Int String where
    cast = show

instance Cast Int Double where
    cast = fromIntegral

如果给出足够的上下文,Haskell知道要使用哪个函数:

cast :: Cast a b => a -> b