Haskell 找出若干相互排斥的、可能不终止的布尔值中哪一个是真的

Haskell 找出若干相互排斥的、可能不终止的布尔值中哪一个是真的,haskell,concurrency,Haskell,Concurrency,(长问题,具体问题在底部) 我正在做一个爱好项目,处理可数类型的子集,我想找出一个特定值属于哪个(可能是无限的)“集” 因此,我得到了一些互斥的、潜在的非终止的、Bool值(在我的例子中,是给定值集合的特征值),这样: 准确地说其中一个将在有限时间内计算为True 其余部分要么在有限时间内计算为False,要么它们的计算不会终止 我的目标是找出哪一个返回True 类型签名最适合我的需要是(我想!) (但我愿意接受这里的建议;如果Int效果更好,我可以在稍后阶段进行b查找) 道德上决定应等同于

(长问题,具体问题在底部)

我正在做一个爱好项目,处理可数类型的子集,我想找出一个特定值属于哪个(可能是无限的)“集”

因此,我得到了一些互斥的、潜在的非终止的、Bool值(在我的例子中,是给定值集合的特征值),这样:

  • 准确地说其中一个将在有限时间内计算为
    True
  • 其余部分要么在有限时间内计算为
    False
    ,要么它们的计算不会终止
我的目标是找出哪一个返回
True

类型签名最适合我的需要是(我想!)

(但我愿意接受这里的建议;如果
Int
效果更好,我可以在稍后阶段进行
b
查找)

道德上决定应等同于snd。(\[x]->x)。过滤fst,如果所有的计算都终止(如果
\[x]->x
爆炸,这是一个程序员错误,我希望早点看到)

下面是一个所需行为的示例(我故意不在示例中使用
偶数
奇数
,因为我使用的集合的指示器函数可能永远不会返回
False
!):


我拼凑了以下代码,这些代码符合我在本例中的要求(可以作为参考实现):

当然看起来好多了!我确信他是一个比我更好的程序员:-)

但在此之前,我想回答以下问题:

  • Haskell平台中是否已经有了
    decise
  • 具有
    unabs
    的解决方案是否具有我想要的相互排他性行为
  • 还有其他重要的问题需要我注意吗

[我意识到,在程序员SE或代码审查SE中,以不太具体的形式提出这个问题可能会更好;我试图以一种明确(哈!)可回答的方式来表述它。]

我认为,您描述的内容对应于这里的可搜索的类:

这里介绍了一个很酷的技巧:


这里还有一些关于进一步研究的幻灯片:

是的,您正确地使用了
unabs
,我认为这解决了您的问题<不幸的是,code>Decise
可能更可靠,因为我们观察到
Unab
在深度嵌套的树中杀死其子代(例如
Unabs
创建的内容)时出现了问题,但理论上
Decise'
是一条可行的道路。我建议你试试看。@luqui:我刚想做这件事,但我想我需要开始编译,玩RTS选项,和/或启动我的Linux虚拟机,因为
让n=10^12::Integer in unab n(last[1..n])
似乎今天不想回来(Win 7上的Haskell Platform 2014.2,没有RTS选项的ghci,unab-0.2.5)。我会再调查一下,因为看起来我做错了什么:-)哦,是的,这是意料之中的
unamb
无法处理那么大的进程树——它实际上是在做
Decision
正在做的事情,所以你可以想象……在我的评论中的示例中,我看到两个值在竞争-
n
last[1..n]
,因此进程树相当小。。。我希望更快的计算速度可以抵消较慢的计算速度,但也许我对
unab
的功能有所误解?您的案例中的一个选项是放弃所有这些,而是考虑一个函数列表
[a->each(Bool,b)a]
,表示各个循环中的步骤。要递归,
zipWith(fmap($))fns声明
。然后,您就可以进行广度优先搜索,无需直接线程。
decide :: [(Bool, b)] -> b
type Natural = Integer
isNatural :: Integer -> Bool
isNatural = (>= 0)

evenOnNatural :: Natural -> Maybe Boolean
evenOnNatural x = decide [( x `elem` [0,2..],     Just True),
                          ( x `elem` [1,3..],     Just False),
                          ( not . isNatural $ x , Nothing)]

-- evenOnNatural 2 should be Just True
-- evenOnNatural 3 should be Just False
-- evenOnNatural (-1) should be Nothing (as it is outside the 'domain')
import Control.Monad(when)
import Control.Concurrent(forkIO,killThread)
import Control.Concurrent.MVar
import System.IO.Unsafe(unsafePerformIO) -- Oh dear!

decide :: [(Bool, a)] -> a
decide xs = unsafePerformIO $ do
    mv <- newEmptyMVar
    let actions = map (\(b,val) -> when b (putMVar mv val)) xs 
    threadIds <- mapM forkIO actions
    result <- takeMVar mv
    mapM_ killThread threadIds -- probably wrong, doesn't kill subthreads
    return result
decide' :: [(Bool, a)] -> a
decide' = unambs . map (uncurry assuming)