Tofu 实例中的模式匹配 [LYAH 示例]
Pattern matching in instances of Tofu [LYAH example]
我在玩 LYAH 的奇怪豆腐示例。我通过从 Frank 构造函数中删除记录字段来稍微简化它,所以就是这样:
class Tofu t where
tofu :: j a -> t a j
data Frank a m = Frank (m a) deriving (Show)
instance Tofu Frank where
tofu x = Frank x
它正在运行并且相当清晰。但是现在我想让 a
类型的值被 tofu
函数修改。所以我开始在实例声明中扩展 x
的值:
instance Tofu Frank where
tofu (m y) = Frank (m y)
结果我得到:
tofu.hs:13:15: Parse error in pattern: m
好的,接下来我尝试在实例声明中进行实际的模式匹配:
instance Tofu Frank where
tofu (Just y) = Frank (Just y)
结果我得到:
tofu.hs:16:15:
Couldn't match type `j' with `Maybe'
`j' is a rigid type variable bound by
the type signature for tofu :: j a -> Frank a j at tofu.hs:16:9
Expected type: j a
Actual type: Maybe a
In the pattern: Just y
In an equation for `tofu': tofu (Just y) = Frank (Just y)
In the instance declaration for `Tofu Frank'
所以,问题是:如何在豆腐的实例声明中使用 a
类型的值?是否可以在不修改 Tofu 的情况下使失败的示例工作 class?
TL;DR:你不能。
假设 t
满足 Tofu t
。函数类型状态
tofu :: j a -> t a j
这实际上意味着
tofu :: forall j a. j a -> t a j -- t is chosen by the class instance
因此,调用者可以选择 j
和 a
是什么。调用者可以传递 [Int]
或 Maybe Char
或 Either String Bool
(此处为 j ~ Either String
和 a ~ Bool
)。函数 tofu
不能假设任何特定情况,并且必须仅使用 "general" 操作来完成它的工作。
how to work with value of type a in instance declaration of tofu
可能没有 a
值。例如
data T a = K Int
因为我们可以将豆腐实例化为
tofu :: T a -> t a T
我们可以像 tofu (K 6 :: T Bool)
那样调用它,即使周围没有 Bool
。
类似的论点适用于
data U a = U (a -> Int)
这里 U Bool
包含一个需要 Bool
的函数,而不是提供或 "containing" 它,松散地说。
我在玩 LYAH 的奇怪豆腐示例。我通过从 Frank 构造函数中删除记录字段来稍微简化它,所以就是这样:
class Tofu t where
tofu :: j a -> t a j
data Frank a m = Frank (m a) deriving (Show)
instance Tofu Frank where
tofu x = Frank x
它正在运行并且相当清晰。但是现在我想让 a
类型的值被 tofu
函数修改。所以我开始在实例声明中扩展 x
的值:
instance Tofu Frank where
tofu (m y) = Frank (m y)
结果我得到:
tofu.hs:13:15: Parse error in pattern: m
好的,接下来我尝试在实例声明中进行实际的模式匹配:
instance Tofu Frank where
tofu (Just y) = Frank (Just y)
结果我得到:
tofu.hs:16:15:
Couldn't match type `j' with `Maybe'
`j' is a rigid type variable bound by
the type signature for tofu :: j a -> Frank a j at tofu.hs:16:9
Expected type: j a
Actual type: Maybe a
In the pattern: Just y
In an equation for `tofu': tofu (Just y) = Frank (Just y)
In the instance declaration for `Tofu Frank'
所以,问题是:如何在豆腐的实例声明中使用 a
类型的值?是否可以在不修改 Tofu 的情况下使失败的示例工作 class?
TL;DR:你不能。
假设 t
满足 Tofu t
。函数类型状态
tofu :: j a -> t a j
这实际上意味着
tofu :: forall j a. j a -> t a j -- t is chosen by the class instance
因此,调用者可以选择 j
和 a
是什么。调用者可以传递 [Int]
或 Maybe Char
或 Either String Bool
(此处为 j ~ Either String
和 a ~ Bool
)。函数 tofu
不能假设任何特定情况,并且必须仅使用 "general" 操作来完成它的工作。
how to work with value of type a in instance declaration of tofu
可能没有 a
值。例如
data T a = K Int
因为我们可以将豆腐实例化为
tofu :: T a -> t a T
我们可以像 tofu (K 6 :: T Bool)
那样调用它,即使周围没有 Bool
。
类似的论点适用于
data U a = U (a -> Int)
这里 U Bool
包含一个需要 Bool
的函数,而不是提供或 "containing" 它,松散地说。