Lan*_*ana 6 haskell functional-programming fixed-point-iteration
我有一个带有以下签名的函数:
simCon :: [Constraint] -> Maybe [Constraint]
Run Code Online (Sandbox Code Playgroud)
我想编写一个方法,以防simCon返回Just [Constraint],我想将它们反馈回simCon并重新运行该方法,并继续这样做,直到输入与输出相同为止。
如果什么都没有,我想终止算法。
如果输入和输出都是相同的类型,我有一些可以工作的东西
fixed :: Eq a => (a -> a) -> a -> a
fixed f a
| a == a' = a
| otherwise = fixed f a'
where a' = f a
Run Code Online (Sandbox Code Playgroud)
但这是行不通的,因为我现在返回Maybe。有人可以建议一种方法来编写类似的函数,但要返回Maybe吗?
我们可以在这里使用绑定函数:
import Data.Bool(bool)
import Control.Monad(liftM2)
fixedM :: (Eq a, Monad m) => (a -> m a) -> a -> m a
fixedM f = go
where go x = f x >>= (liftM2 bool go pure <*> (x ==))
Run Code Online (Sandbox Code Playgroud)
更详细的实现是:
fixedM :: (Eq a, Monad m) => (a -> m a) -> a -> m a
fixedM f x = do
x' <- f x
if x == x'
then pure x'
else fixedM f x'
Run Code Online (Sandbox Code Playgroud)
因此我们首先x'用进行计算f x。如果f x返回Just x',那么我们继续。如果f xreturn Nothing,fixedM也会返回Nothing。然后我们x与进行比较x'。如果两者相等,我们返回pure x',否则我们递归fixedM f x'。
或者,我们可以使用模式匹配,尽管这基本上使绑定运算符显式化(并且仅适用于 a Maybe):
import Control.Monad(ap)
fixedM :: Eq a => (a -> Maybe a) -> a -> Maybe a
fixedM f = ap go f
where go x (Just x') | x == x' = go x' (f x')
| otherwise = Just x'
go _ _ = Nothing
Run Code Online (Sandbox Code Playgroud)
我们可以通过使用模式保护使其更加紧凑:
fixedM :: Eq a => (a -> Maybe a) -> a -> Maybe a
fixedM f = go
where go x | Just x' <- f x = bool (go x) (Just x) (x == x')
| otherwise = Nothing
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |