2015-10-12 42 views
0

我正在实现一个使用anotherFunction的函数myFunction获取Haskell中Maybe的值

anotherFunction是一个无法修改的外部函数。它返回一个Maybe类型的值。

myFunction是递归函数,用于检查另一个myFunction返回的值是Just值还是Nothing。如果是Nothing则返回Nothing,否则将使用myFunction返回的纯值作为参数anotherFunction

基本上是这样的:

--These cannot be modified 

data A = B | F a 

anotherFunction :: x -> Maybe x 
--Something here 

myFunction :: A -> Maybe x 

--These can be modified 
myFunction (F a) = {- if (myFunction a == Nothing) 
         then Nothing 
         else anotherFunction (pure value of (myFunction a)) -} 

如何才能实现这一目标?

+3

使用case语句。在Haskell中正常函数(不是构造函数)中的 – user1937198

+2

通常以小写字母开头。 – jakubdaniel

+1

不仅____它们通常以小写字母开头,它们必须以小写字母开头才能在Haskell中允许。我相应地编辑了这个问题。 - - (原则上,下划线也可以作为变量名的第一个字符,但不要这样做 - [下划线有特殊含义](http://stackoverflow.com/questions/21282515/is- – leftaroundabout

回答

2

可以搭配使用caseMyFunction返回值:

case (myFunction a) of 
    Nothing -> Nothing 
    Just x -> anotherFunction x 

但是一个更简洁的方法是使用>>=

(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b 
myFunction (f a) = (myFunction a) >>= anotherFunction 

,或者您可以使用do符号:

myFunction (f a) = do 
    x <- myFunction a 
    anotherFunction x 
2

除非签名中有约束条件Eq a => Maybe a,否则您将无法使用==。做这类事情的最好方法是使用case声明:

case m of 
    Just x -> anotherFunction x 
    Nothing -> Nothing 

这种模式是Maybe如此普遍,它形成了Monad实例Maybe,给你的功能return x = Just xf >>= x = case x of Just a -> f a; Nothing -> Nothing

+1

不要把它称为'也许',这是Prelude函数的名字 – Zeta

+0

@Zeta谢谢你,改变了。 –

1

Suppo如果您有fg,它们都会生成包装在MaybeJust 3Just "three",Nothing)类型中的值。您可以撰写两个这样的:

import Control.Monad 

f :: a -> Maybe b -- suppose these two are signatures of the given two functions 
g :: b -> Maybe c 

h :: a -> Maybe c -- this is the way you pass values from one 
h = f >=> g  -- to the other and bail out when you see Nothing 

我已经使用便于记忆的名称为类型ab,并c使组合物更加清晰,但要注意的是,类型不约束,在一个a签名无关在另一个签名中使用a,实际类型是在两个函数在具体上下文中使用时决定的。

由于您似乎没有对aF a构造函数进行任何约束,我想您希望它可能与A不同。在这种情况下,函数myFunction不能有类型A -> ...,因为您试图通过a作为参数。