Haskell中是否有任何类型为a -> b
的函数?这意味着,是否可以编写一个f :: a -> b
的函数?我不认为这样的函数存在的原因如下:假设我们发现f f :: a -> b
,f 2
会产生什么?类型b
的值,但是什么是b
,因为Haskell不能从我给出的参数中推断(我认为)它?它是否正确?否则,你能给我一个这样的功能的例子吗?
答案 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
具有固定类型Int
,fromIntegral (length l) :: b
必须具有适合环境的固定类型Double
,并且与大多数其他语言不同类型推断,来自环境的信息可以用基于Hindley-Milner的语言获得。
不,f :: a -> b
的问题在于您可以将a
和b
实例化为任何类型的荒谬组合,而不仅仅是不同的数字类型。因为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