2017-02-13 79 views
2

我正在试验Haskell,我想知道为什么我无法匹配Just包含一对。我对这种语言没有多少经验,我完全迷失了方向。模式匹配只包含一对

f :: Int -> Maybe (Int, [Int]) 
f 100 = Nothing 
f x = Just (x,[x]) 

g :: Int -> Maybe Int 
g x 
| u==Nothing = Nothing 
| u==(Just (r,s)) = Just r 
where 
    u=f x 

那么这段代码有什么问题。 GHC说rs不在范围内。

+0

将范围问题放在一边,使用'=='会引入一个不需要的“Eq”约束。 – chepner

回答

6

因为守卫表达式不能做模式匹配。

Guard表达式就像一个布尔表达式,它不能做绑定。它只是使用|之前的绑定,在这种情况下为x

因此,工作解决方案将是这样的。

g :: Int -> Maybe Int 
g x = case f x of 
    Nothing -> Nothing 
    Just (r,_) -> Just r 
+2

*“因为警卫表现...”*。那么'g x |只是(r,s)< - u = ...'?你可以绑定/匹配一名警卫。你只需要使用正确的语法。 '=='不正确。 – Zeta

+0

@Zeta我只是不知道'PatternGuard'是Haskell2010的默认值。感谢您的通知。我将离开我对Haskell98案件的回答,并且您的答案已经发布。 – jeiea

4

您可以使用case expressions

g :: Int -> Maybe Int 
g x = 
    case f x of 
    Nothing -> Nothing 
    Just (r,s) -> Just r 
7

如果要在保护模式匹配,你必须使用一个pattern guard

g :: Int -> Maybe Int 
g x 
    | Just (r,_) <- u = Just r 
    | otherwise  = Nothing 
    where 
    u = f x 

毕竟,(==)是一个普通的功能,你需要双方值来使用它。由于中的rs未知,因此编译器会为您提供错误消息。

顺便说一句,采取Maybe并返回Nothing如果该值是一个函数hJust x是如此普遍NothingJust (h x),它形成了一个模式:fmap。您可以编写

g :: Int -> Maybe Int 
g x = fmap fst (f x)