如何在Haskell中对中间值进行模式匹配

时间:2019-12-07 14:13:16

标签: haskell

问题

在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)。我该怎么办?

1 个答案:

答案 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();
        }
    }

这也将使编译器基本上无法知道您的模式是否完整(即,没有任何情况下无法匹配的值)