类型的约束多态性

kek*_*coh 4 haskell

我尝试定义受约束的多态值列表,例如

myList = ["foo", 5] :: [Show a => a]
Run Code Online (Sandbox Code Playgroud)

这会产生以下错误(GHCi,版本 8.6.5)

GHC 尚不支持不可预测的多态性

无论如何,是否可以指定一种类型,例如,表单的函数f :: Show a => [a] -> [String]可以使用上述受约束的值?

换句话说,有没有办法让编译器验证下面的代码?

(++ "fork") . show <$> ["foo", 5]
Run Code Online (Sandbox Code Playgroud)

我目前尝试Show通过定义值和预期结果的数据集来测试GADT的类型类实例[(value, "expectedResult")]。但是,由于 GADT 的构造函数指定了值类型,因此不可能天真地做到这一点。

lef*_*out 6

[Show a => a]并不意味着你认为它的作用。它是 的简写[? a . Show a => a],即一个值列表,每个都是多态的,而不是包含具体(但未知)类型的多态列表。那将是一个存在主义的, [? a . Show a => a]

虽然 Haskell 在类型表达式中没有匿名存在,但可以将它们作为声明类型获取:

{-# LANGUAGE GADTs #-}

data Showable where
  Showable :: Show a => a -> Showable

myList :: [Showable]
myList = [Showable "foo", Showable 5]
Run Code Online (Sandbox Code Playgroud)
Main*> map (\(Showable x) -> show x ++ "fork") myList 
["\"foo\"fork","5fork"]
Run Code Online (Sandbox Code Playgroud)

但是,正如 chi 已经评论过的那样,这样做没有意义:您对 Show 约束的存在主义所能做的就是,好吧,show it。即,它的所有信息都可以在一个字符串中捕获。好吧,然后立即存储字符串

myList :: [String]
myList = [show "foo", show 5]
Run Code Online (Sandbox Code Playgroud)

  • 对于 `Show` 来说甚至不是 100% 正确,因为 `showsPrec` 确实有更多的信息。不过,即使对于多方法类,您始终可以做的就是将所有方法简单地存储为部分应用的函数。 (2认同)