gpt4 book ai didi

haskell - 如何在haskell中编写定点函数

转载 作者:行者123 更新时间:2023-12-04 15:17:18 26 4
gpt4 key购买 nike

我有一个具有以下签名的函数:

simCon :: [Constraint] -> Maybe [Constraint]

我想写一个方法,如果 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

但这行不通,因为我现在返回一个 Maybe 。有人可以建议一种编写类似函数但返回类型为 Maybe 的方法吗?

最佳答案

我们可以在这里使用绑定(bind)函数:

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 ==))

更详细的实现是:
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'

因此我们首先计算 x'f x .万一 f x返回 Just x' ,然后我们继续。万一 f x返回 Nothing , fixedM将返回 Nothing也是。然后我们比较 xx' .如果两者相等,我们返回 pure x' , 否则我们在 fixedM f x' 上递归.

或者,我们可以使用模式匹配,尽管这基本上使绑定(bind)运算符显式(并且仅适用于 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

我们可以通过使用模式保护使其更紧凑:
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

关于haskell - 如何在haskell中编写定点函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56693849/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com