在Bartosz Milewski撰写的《程序员的类别理论》 一书中,第4.3章。
您必须编写一个态射是部分函数的Kleisli类别。这是我无法编译的尝试:
data Optional a = Valid a | Invalid deriving (Show)
return :: a -> Optional a
return x = Valid x
(>=>) :: (a -> Optional b) -> (b -> Optional c) -> (a -> Optional c)
f (>=>) g = \x ->
let s = f x
in | s == Valid v = g v
| s == Invalid = Invalid
在>=>
运算符定义中,我想对中间值s
进行模式匹配以测试是否为Valid
(然后调用f
)或是否为Invalid
(然后返回Invalid
)。我该怎么办?
答案 0 :(得分:4)
您可以使用f >=> g = \x ->
case f x of
Valid v -> g v
Invalid -> Invalid
进行模式匹配:
(==)
在您的问题中,您似乎还试图使用防护措施来进行模式匹配和绑定值。 Haskell不允许这样做。保护只是一个布尔值表达式,必须与前面的(有时是可选的)模式匹配才为true。 Haskell语言并没有真正将v
运算符“理解”为相等。它只是将其视为其他函数。确实,可以为一种类型定义它,使其不与模式匹配所需的同种类型对应。
允许后卫使用模式(或更大范围)中的变量,但不能像模式那样绑定新变量。因此,这是错误的,因为f >=> g = \x ->
case f x of
_ | x == Valid v -> g v
_ | x == Invalid -> Invalid
是不确定的。
public void ShowSP(bool isClick, Projet projet)
{
if (isClick)
{
clearProjectPanel();
foreach (var sousProjet in projet.sousProjects)
{
int x = 0, y = 0;
UserControl_sousProjet userControl = new UserControl_sousProjet(sousProjet);
userControl.Location = new Point(x, y);
panel_projects.Controls.Add(userControl);
y += userControl.Height;
}
}
else
{
refreshProject();
}
}
这也将使编译器基本上无法知道您的模式是否完整(即,没有任何情况下无法匹配的值)