{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
module Algorithm.Search (
bfs,
dfs,
dijkstra,
dijkstraAssoc,
aStar,
aStarAssoc,
bfsM,
dfsM,
dijkstraM,
aStarM,
incrementalCosts,
incrementalCostsM,
pruning,
pruningM
) where
import qualified Data.Map as Map
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import qualified Data.List as List
import qualified Data.Foldable as Foldable
import Data.Functor.Identity (Identity(..))
import Control.Monad (filterM, zipWithM)
bfs :: (Foldable f, Ord state)
=> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
bfs :: (state -> f state) -> (state -> Bool) -> state -> Maybe [state]
bfs =
Seq state
-> (state -> state)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
forall (f :: * -> *) container stateKey state.
(Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
generalizedSearch Seq state
forall a. Seq a
Seq.empty state -> state
forall a. a -> a
id (\[state]
_ [state]
_ -> Bool
False)
dfs :: (Foldable f, Ord state)
=> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
dfs :: (state -> f state) -> (state -> Bool) -> state -> Maybe [state]
dfs =
[state]
-> (state -> state)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
forall (f :: * -> *) container stateKey state.
(Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
generalizedSearch [] state -> state
forall a. a -> a
id (\[state]
_ [state]
_ -> Bool
True)
dijkstra :: (Foldable f, Num cost, Ord cost, Ord state)
=> (state -> f state)
-> (state -> state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
dijkstra :: (state -> f state)
-> (state -> state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
dijkstra state -> f state
next state -> state -> cost
cost state -> Bool
found state
initial =
(state -> [(state, cost)])
-> (state -> Bool) -> state -> Maybe (cost, [state])
forall cost state.
(Num cost, Ord cost, Ord state) =>
(state -> [(state, cost)])
-> (state -> Bool) -> state -> Maybe (cost, [state])
dijkstraAssoc state -> [(state, cost)]
next' state -> Bool
found state
initial
where
next' :: state -> [(state, cost)]
next' state
st = (state -> (state, cost)) -> [state] -> [(state, cost)]
forall a b. (a -> b) -> [a] -> [b]
map (\state
new_st -> (state
new_st, state -> state -> cost
cost state
st state
new_st)) ([state] -> [(state, cost)]) -> [state] -> [(state, cost)]
forall a b. (a -> b) -> a -> b
$
f state -> [state]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList (state -> f state
next state
st)
dijkstraAssoc :: (Num cost, Ord cost, Ord state)
=> (state -> [(state, cost)])
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
dijkstraAssoc :: (state -> [(state, cost)])
-> (state -> Bool) -> state -> Maybe (cost, [state])
dijkstraAssoc state -> [(state, cost)]
next state -> Bool
found state
initial =
[(cost, state)] -> (cost, [state])
forall a a. Num a => [(a, a)] -> (a, [a])
unpack ([(cost, state)] -> (cost, [state]))
-> Maybe [(cost, state)] -> Maybe (cost, [state])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
LIFOHeap cost state
-> ((cost, state) -> state)
-> ([(cost, state)] -> [(cost, state)] -> Bool)
-> ((cost, state) -> [(cost, state)])
-> ((cost, state) -> Bool)
-> (cost, state)
-> Maybe [(cost, state)]
forall (f :: * -> *) container stateKey state.
(Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
generalizedSearch LIFOHeap cost state
forall k a. LIFOHeap k a
emptyLIFOHeap (cost, state) -> state
forall a b. (a, b) -> b
snd [(cost, state)] -> [(cost, state)] -> Bool
forall a b. Ord a => [(a, b)] -> [(a, b)] -> Bool
leastCostly (cost, state) -> [(cost, state)]
next' (state -> Bool
found (state -> Bool)
-> ((cost, state) -> state) -> (cost, state) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (cost, state) -> state
forall a b. (a, b) -> b
snd)
(cost
0, state
initial)
where
next' :: (cost, state) -> [(cost, state)]
next' (cost
old_cost, state
st) =
(\(state
new_st, cost
new_cost) -> (cost
new_cost cost -> cost -> cost
forall a. Num a => a -> a -> a
+ cost
old_cost, state
new_st))
((state, cost) -> (cost, state))
-> [(state, cost)] -> [(cost, state)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (state -> [(state, cost)]
next state
st)
unpack :: [(a, a)] -> (a, [a])
unpack [] = (a
0, [])
unpack [(a, a)]
packed_states = ((a, a) -> a
forall a b. (a, b) -> a
fst ((a, a) -> a) -> ([(a, a)] -> (a, a)) -> [(a, a)] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, a)] -> (a, a)
forall a. [a] -> a
last ([(a, a)] -> a) -> [(a, a)] -> a
forall a b. (a -> b) -> a -> b
$ [(a, a)]
packed_states, ((a, a) -> a) -> [(a, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, a) -> a
forall a b. (a, b) -> b
snd [(a, a)]
packed_states)
aStar :: (Foldable f, Num cost, Ord cost, Ord state)
=> (state -> f state)
-> (state -> state -> cost)
-> (state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
aStar :: (state -> f state)
-> (state -> state -> cost)
-> (state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
aStar state -> f state
next state -> state -> cost
cost state -> cost
remaining state -> Bool
found state
initial =
(state -> [(state, cost)])
-> (state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
forall cost state.
(Num cost, Ord cost, Ord state) =>
(state -> [(state, cost)])
-> (state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
aStarAssoc state -> [(state, cost)]
next' state -> cost
remaining state -> Bool
found state
initial
where
next' :: state -> [(state, cost)]
next' state
st = (state -> (state, cost)) -> [state] -> [(state, cost)]
forall a b. (a -> b) -> [a] -> [b]
map (\state
new_st -> (state
new_st, state -> state -> cost
cost state
st state
new_st)) ([state] -> [(state, cost)]) -> [state] -> [(state, cost)]
forall a b. (a -> b) -> a -> b
$
f state -> [state]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList (state -> f state
next state
st)
aStarAssoc :: (Num cost, Ord cost, Ord state)
=> (state -> [(state, cost)])
-> (state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
aStarAssoc :: (state -> [(state, cost)])
-> (state -> cost)
-> (state -> Bool)
-> state
-> Maybe (cost, [state])
aStarAssoc state -> [(state, cost)]
next state -> cost
remaining state -> Bool
found state
initial =
[(cost, (cost, state))] -> (cost, [state])
forall a a a. Num a => [(a, (a, a))] -> (a, [a])
unpack ([(cost, (cost, state))] -> (cost, [state]))
-> Maybe [(cost, (cost, state))] -> Maybe (cost, [state])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LIFOHeap cost (cost, state)
-> ((cost, (cost, state)) -> state)
-> ([(cost, (cost, state))] -> [(cost, (cost, state))] -> Bool)
-> ((cost, (cost, state)) -> [(cost, (cost, state))])
-> ((cost, (cost, state)) -> Bool)
-> (cost, (cost, state))
-> Maybe [(cost, (cost, state))]
forall (f :: * -> *) container stateKey state.
(Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
generalizedSearch LIFOHeap cost (cost, state)
forall k a. LIFOHeap k a
emptyLIFOHeap (cost, (cost, state)) -> state
forall a a c. (a, (a, c)) -> c
snd2 [(cost, (cost, state))] -> [(cost, (cost, state))] -> Bool
forall a b. Ord a => [(a, b)] -> [(a, b)] -> Bool
leastCostly (cost, (cost, state)) -> [(cost, (cost, state))]
next'
(state -> Bool
found (state -> Bool)
-> ((cost, (cost, state)) -> state)
-> (cost, (cost, state))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (cost, (cost, state)) -> state
forall a a c. (a, (a, c)) -> c
snd2) (state -> cost
remaining state
initial, (cost
0, state
initial))
where
next' :: (cost, (cost, state)) -> [(cost, (cost, state))]
next' (cost
_, (cost
old_cost, state
old_st)) =
(state, cost) -> (cost, (cost, state))
update_state ((state, cost) -> (cost, (cost, state)))
-> [(state, cost)] -> [(cost, (cost, state))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (state -> [(state, cost)]
next state
old_st)
where
update_state :: (state, cost) -> (cost, (cost, state))
update_state (state
new_st, cost
cost) =
let new_cost :: cost
new_cost = cost
old_cost cost -> cost -> cost
forall a. Num a => a -> a -> a
+ cost
cost
new_est :: cost
new_est = cost
new_cost cost -> cost -> cost
forall a. Num a => a -> a -> a
+ state -> cost
remaining state
new_st
in (cost
new_est, (cost
new_cost, state
new_st))
unpack :: [(a, (a, a))] -> (a, [a])
unpack [] = (a
0, [])
unpack [(a, (a, a))]
packed_states =
((a, a) -> a
forall a b. (a, b) -> a
fst ((a, a) -> a) -> ([(a, (a, a))] -> (a, a)) -> [(a, (a, a))] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, (a, a)) -> (a, a)
forall a b. (a, b) -> b
snd ((a, (a, a)) -> (a, a))
-> ([(a, (a, a))] -> (a, (a, a))) -> [(a, (a, a))] -> (a, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, (a, a))] -> (a, (a, a))
forall a. [a] -> a
last ([(a, (a, a))] -> a) -> [(a, (a, a))] -> a
forall a b. (a -> b) -> a -> b
$ [(a, (a, a))]
packed_states, ((a, (a, a)) -> a) -> [(a, (a, a))] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, (a, a)) -> a
forall a a c. (a, (a, c)) -> c
snd2 [(a, (a, a))]
packed_states)
snd2 :: (a, (a, c)) -> c
snd2 = (a, c) -> c
forall a b. (a, b) -> b
snd ((a, c) -> c) -> ((a, (a, c)) -> (a, c)) -> (a, (a, c)) -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, (a, c)) -> (a, c)
forall a b. (a, b) -> b
snd
bfsM :: (Monad m, Foldable f, Ord state)
=> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
bfsM :: (state -> m (f state))
-> (state -> m Bool) -> state -> m (Maybe [state])
bfsM = Seq state
-> (state -> state)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM Seq state
forall a. Seq a
Seq.empty state -> state
forall a. a -> a
id (\[state]
_ [state]
_ -> Bool
False)
dfsM :: (Monad m, Foldable f, Ord state)
=> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
dfsM :: (state -> m (f state))
-> (state -> m Bool) -> state -> m (Maybe [state])
dfsM =
[state]
-> (state -> state)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM [] state -> state
forall a. a -> a
id (\[state]
_ [state]
_ -> Bool
True)
dijkstraM :: (Monad m, Foldable f, Num cost, Ord cost, Ord state)
=> (state -> m (f state))
-> (state -> state -> m cost)
-> (state -> m Bool)
-> state
-> m (Maybe (cost, [state]))
dijkstraM :: (state -> m (f state))
-> (state -> state -> m cost)
-> (state -> m Bool)
-> state
-> m (Maybe (cost, [state]))
dijkstraM state -> m (f state)
nextM state -> state -> m cost
costM state -> m Bool
foundM state
initial =
([(cost, state)] -> (cost, [state]))
-> m (Maybe [(cost, state)]) -> m (Maybe (cost, [state]))
forall (f1 :: * -> *) (f2 :: * -> *) a b.
(Functor f1, Functor f2) =>
(a -> b) -> f1 (f2 a) -> f1 (f2 b)
fmap2 [(cost, state)] -> (cost, [state])
forall a a. Num a => [(a, a)] -> (a, [a])
unpack (m (Maybe [(cost, state)]) -> m (Maybe (cost, [state])))
-> m (Maybe [(cost, state)]) -> m (Maybe (cost, [state]))
forall a b. (a -> b) -> a -> b
$ LIFOHeap cost state
-> ((cost, state) -> state)
-> ([(cost, state)] -> [(cost, state)] -> Bool)
-> ((cost, state) -> m [(cost, state)])
-> ((cost, state) -> m Bool)
-> (cost, state)
-> m (Maybe [(cost, state)])
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM LIFOHeap cost state
forall k a. LIFOHeap k a
emptyLIFOHeap (cost, state) -> state
forall a b. (a, b) -> b
snd [(cost, state)] -> [(cost, state)] -> Bool
forall a b. Ord a => [(a, b)] -> [(a, b)] -> Bool
leastCostly (cost, state) -> m [(cost, state)]
nextM'
(state -> m Bool
foundM (state -> m Bool)
-> ((cost, state) -> state) -> (cost, state) -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (cost, state) -> state
forall a b. (a, b) -> b
snd) (cost
0, state
initial)
where
nextM' :: (cost, state) -> m [(cost, state)]
nextM' (cost
old_cost, state
old_st) = do
[state]
new_states <- f state -> [state]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList (f state -> [state]) -> m (f state) -> m [state]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> state -> m (f state)
nextM state
old_st
[cost]
incr_costs <- [m cost] -> m [cost]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([m cost] -> m [cost]) -> [m cost] -> m [cost]
forall a b. (a -> b) -> a -> b
$ state -> state -> m cost
costM state
old_st (state -> m cost) -> [state] -> [m cost]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [state]
new_states
let new_costs :: [cost]
new_costs = (cost -> cost -> cost
forall a. Num a => a -> a -> a
+ cost
old_cost) (cost -> cost) -> [cost] -> [cost]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [cost]
incr_costs
[(cost, state)] -> m [(cost, state)]
forall (m :: * -> *) a. Monad m => a -> m a
return ([(cost, state)] -> m [(cost, state)])
-> [(cost, state)] -> m [(cost, state)]
forall a b. (a -> b) -> a -> b
$ [cost] -> [state] -> [(cost, state)]
forall a b. [a] -> [b] -> [(a, b)]
zip [cost]
new_costs [state]
new_states
unpack :: [(a, a)] -> (a, [a])
unpack [] = (a
0, [])
unpack [(a, a)]
packed_states = ((a, a) -> a
forall a b. (a, b) -> a
fst ((a, a) -> a) -> ([(a, a)] -> (a, a)) -> [(a, a)] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, a)] -> (a, a)
forall a. [a] -> a
last ([(a, a)] -> a) -> [(a, a)] -> a
forall a b. (a -> b) -> a -> b
$ [(a, a)]
packed_states, ((a, a) -> a) -> [(a, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, a) -> a
forall a b. (a, b) -> b
snd [(a, a)]
packed_states)
aStarM :: (Monad m, Foldable f, Num cost, Ord cost, Ord state)
=> (state -> m (f state))
-> (state -> state -> m cost)
-> (state -> m cost)
-> (state -> m Bool)
-> state
-> m (Maybe (cost, [state]))
aStarM :: (state -> m (f state))
-> (state -> state -> m cost)
-> (state -> m cost)
-> (state -> m Bool)
-> state
-> m (Maybe (cost, [state]))
aStarM state -> m (f state)
nextM state -> state -> m cost
costM state -> m cost
remainingM state -> m Bool
foundM state
initial = do
cost
remaining_init <- state -> m cost
remainingM state
initial
([(cost, (cost, state))] -> (cost, [state]))
-> m (Maybe [(cost, (cost, state))]) -> m (Maybe (cost, [state]))
forall (f1 :: * -> *) (f2 :: * -> *) a b.
(Functor f1, Functor f2) =>
(a -> b) -> f1 (f2 a) -> f1 (f2 b)
fmap2 [(cost, (cost, state))] -> (cost, [state])
forall a a a. Num a => [(a, (a, a))] -> (a, [a])
unpack (m (Maybe [(cost, (cost, state))]) -> m (Maybe (cost, [state])))
-> m (Maybe [(cost, (cost, state))]) -> m (Maybe (cost, [state]))
forall a b. (a -> b) -> a -> b
$ LIFOHeap cost (cost, state)
-> ((cost, (cost, state)) -> state)
-> ([(cost, (cost, state))] -> [(cost, (cost, state))] -> Bool)
-> ((cost, (cost, state)) -> m [(cost, (cost, state))])
-> ((cost, (cost, state)) -> m Bool)
-> (cost, (cost, state))
-> m (Maybe [(cost, (cost, state))])
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM LIFOHeap cost (cost, state)
forall k a. LIFOHeap k a
emptyLIFOHeap (cost, (cost, state)) -> state
forall a a c. (a, (a, c)) -> c
snd2 [(cost, (cost, state))] -> [(cost, (cost, state))] -> Bool
forall a b. Ord a => [(a, b)] -> [(a, b)] -> Bool
leastCostly (cost, (cost, state)) -> m [(cost, (cost, state))]
nextM'
(state -> m Bool
foundM (state -> m Bool)
-> ((cost, (cost, state)) -> state)
-> (cost, (cost, state))
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (cost, (cost, state)) -> state
forall a a c. (a, (a, c)) -> c
snd2) (cost
remaining_init, (cost
0, state
initial))
where
nextM' :: (cost, (cost, state)) -> m [(cost, (cost, state))]
nextM' (cost
_, (cost
old_cost, state
old_st)) = do
[state]
new_states <- f state -> [state]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList (f state -> [state]) -> m (f state) -> m [state]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> state -> m (f state)
nextM state
old_st
[m (cost, (cost, state))] -> m [(cost, (cost, state))]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([m (cost, (cost, state))] -> m [(cost, (cost, state))])
-> [m (cost, (cost, state))] -> m [(cost, (cost, state))]
forall a b. (a -> b) -> a -> b
$ state -> m (cost, (cost, state))
update_stateM (state -> m (cost, (cost, state)))
-> [state] -> [m (cost, (cost, state))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [state]
new_states
where
update_stateM :: state -> m (cost, (cost, state))
update_stateM state
new_st = do
cost
remaining <- state -> m cost
remainingM state
new_st
cost
cost <- state -> state -> m cost
costM state
old_st state
new_st
let new_cost :: cost
new_cost = cost
old_cost cost -> cost -> cost
forall a. Num a => a -> a -> a
+ cost
cost
new_est :: cost
new_est = cost
new_cost cost -> cost -> cost
forall a. Num a => a -> a -> a
+ cost
remaining
(cost, (cost, state)) -> m (cost, (cost, state))
forall (m :: * -> *) a. Monad m => a -> m a
return (cost
new_est, (cost
new_cost, state
new_st))
unpack :: [(a, (a, a))] -> (a, [a])
unpack [] = (a
0, [])
unpack [(a, (a, a))]
packed_states =
((a, a) -> a
forall a b. (a, b) -> a
fst ((a, a) -> a) -> ([(a, (a, a))] -> (a, a)) -> [(a, (a, a))] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, (a, a)) -> (a, a)
forall a b. (a, b) -> b
snd ((a, (a, a)) -> (a, a))
-> ([(a, (a, a))] -> (a, (a, a))) -> [(a, (a, a))] -> (a, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(a, (a, a))] -> (a, (a, a))
forall a. [a] -> a
last ([(a, (a, a))] -> a) -> [(a, (a, a))] -> a
forall a b. (a -> b) -> a -> b
$ [(a, (a, a))]
packed_states, ((a, (a, a)) -> a) -> [(a, (a, a))] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, (a, a)) -> a
forall a a c. (a, (a, c)) -> c
snd2 [(a, (a, a))]
packed_states)
snd2 :: (a, (a, c)) -> c
snd2 = (a, c) -> c
forall a b. (a, b) -> b
snd ((a, c) -> c) -> ((a, (a, c)) -> (a, c)) -> (a, (a, c)) -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, (a, c)) -> (a, c)
forall a b. (a, b) -> b
snd
incrementalCosts ::
(state -> state -> cost)
-> [state]
-> [cost]
incrementalCosts :: (state -> state -> cost) -> [state] -> [cost]
incrementalCosts state -> state -> cost
cost_fn [state]
states = (state -> state -> cost) -> [state] -> [state] -> [cost]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith state -> state -> cost
cost_fn [state]
states ([state] -> [state]
forall a. [a] -> [a]
tail [state]
states)
incrementalCostsM ::
(Monad m) =>
(state -> state -> m cost)
-> [state]
-> m [cost]
incrementalCostsM :: (state -> state -> m cost) -> [state] -> m [cost]
incrementalCostsM state -> state -> m cost
costM [state]
states = (state -> state -> m cost) -> [state] -> [state] -> m [cost]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM state -> state -> m cost
costM [state]
states ([state] -> [state]
forall a. [a] -> [a]
tail [state]
states)
pruning ::
(Foldable f)
=> (a -> f a)
-> (a -> Bool)
-> (a -> [a])
a -> f a
next pruning :: (a -> f a) -> (a -> Bool) -> a -> [a]
`pruning` a -> Bool
predicate =
((a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
predicate) ([a] -> [a]) -> (f a -> [a]) -> f a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList) (f a -> [a]) -> (a -> f a) -> a -> [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
next
pruningM ::
(Monad m, Foldable f)
=> (a -> m (f a))
-> (a -> m Bool)
-> (a -> m [a])
pruningM :: (a -> m (f a)) -> (a -> m Bool) -> a -> m [a]
pruningM a -> m (f a)
nextM a -> m Bool
predicateM a
a = do
f a
next_states <- a -> m (f a)
nextM a
a
(a -> m Bool) -> [a] -> m [a]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM ((Bool -> Bool) -> m Bool -> m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> Bool
not(m Bool -> m Bool) -> (a -> m Bool) -> a -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m Bool
predicateM) ([a] -> m [a]) -> [a] -> m [a]
forall a b. (a -> b) -> a -> b
$ f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Foldable.toList f a
next_states
data SearchState container stateKey state = SearchState {
SearchState container stateKey state -> state
current :: state,
SearchState container stateKey state -> container
queue :: container,
SearchState container stateKey state -> Set stateKey
visited :: Set.Set stateKey,
SearchState container stateKey state -> Map stateKey [state]
paths :: Map.Map stateKey [state]
}
generalizedSearch ::
(Foldable f, SearchContainer container, Ord stateKey, Elem container ~ state)
=> container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
generalizedSearch :: container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> f state)
-> (state -> Bool)
-> state
-> Maybe [state]
generalizedSearch container
empty state -> stateKey
mk_key [state] -> [state] -> Bool
better state -> f state
next state -> Bool
found state
initial = Identity (Maybe [state]) -> Maybe [state]
forall a. Identity a -> a
runIdentity (Identity (Maybe [state]) -> Maybe [state])
-> Identity (Maybe [state]) -> Maybe [state]
forall a b. (a -> b) -> a -> b
$
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> Identity (f state))
-> (state -> Identity Bool)
-> state
-> Identity (Maybe [state])
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM container
empty state -> stateKey
mk_key [state] -> [state] -> Bool
better (f state -> Identity (f state)
forall a. a -> Identity a
Identity (f state -> Identity (f state))
-> (state -> f state) -> state -> Identity (f state)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. state -> f state
next) (Bool -> Identity Bool
forall a. a -> Identity a
Identity (Bool -> Identity Bool)
-> (state -> Bool) -> state -> Identity Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. state -> Bool
found) state
initial
nextSearchStateM ::
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state)
=> ([state] -> [state] -> Bool)
-> (state -> stateKey)
-> (state -> m (f state))
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
nextSearchStateM :: ([state] -> [state] -> Bool)
-> (state -> stateKey)
-> (state -> m (f state))
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
nextSearchStateM [state] -> [state] -> Bool
better state -> stateKey
mk_key state -> m (f state)
nextM SearchState container stateKey state
old = do
(container
new_queue, Map stateKey [state]
new_paths) <- m (container, Map stateKey [state])
new_queue_paths_M
let new_state_May :: Maybe (SearchState container stateKey state)
new_state_May = Map stateKey [state]
-> (state, container) -> SearchState container stateKey state
mk_search_state Map stateKey [state]
new_paths ((state, container) -> SearchState container stateKey state)
-> Maybe (state, container)
-> Maybe (SearchState container stateKey state)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> container -> Maybe (Elem container, container)
forall container.
SearchContainer container =>
container -> Maybe (Elem container, container)
pop container
new_queue
case Maybe (SearchState container stateKey state)
new_state_May of
Just SearchState container stateKey state
new_state ->
if state -> stateKey
mk_key (SearchState container stateKey state -> state
forall container stateKey state.
SearchState container stateKey state -> state
current SearchState container stateKey state
new_state) stateKey -> Set stateKey -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` SearchState container stateKey state -> Set stateKey
forall container stateKey state.
SearchState container stateKey state -> Set stateKey
visited SearchState container stateKey state
old
then ([state] -> [state] -> Bool)
-> (state -> stateKey)
-> (state -> m (f state))
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
([state] -> [state] -> Bool)
-> (state -> stateKey)
-> (state -> m (f state))
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
nextSearchStateM [state] -> [state] -> Bool
better state -> stateKey
mk_key state -> m (f state)
nextM SearchState container stateKey state
new_state
else Maybe (SearchState container stateKey state)
-> m (Maybe (SearchState container stateKey state))
forall (m :: * -> *) a. Monad m => a -> m a
return (SearchState container stateKey state
-> Maybe (SearchState container stateKey state)
forall a. a -> Maybe a
Just SearchState container stateKey state
new_state)
Maybe (SearchState container stateKey state)
Nothing -> Maybe (SearchState container stateKey state)
-> m (Maybe (SearchState container stateKey state))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (SearchState container stateKey state)
forall a. Maybe a
Nothing
where
mk_search_state :: Map stateKey [state]
-> (state, container) -> SearchState container stateKey state
mk_search_state Map stateKey [state]
new_paths (state
new_current, container
remaining_queue) = SearchState :: forall container stateKey state.
state
-> container
-> Set stateKey
-> Map stateKey [state]
-> SearchState container stateKey state
SearchState {
current :: state
current = state
new_current,
queue :: container
queue = container
remaining_queue,
visited :: Set stateKey
visited = stateKey -> Set stateKey -> Set stateKey
forall a. Ord a => a -> Set a -> Set a
Set.insert (state -> stateKey
mk_key state
new_current) (SearchState container stateKey state -> Set stateKey
forall container stateKey state.
SearchState container stateKey state -> Set stateKey
visited SearchState container stateKey state
old),
paths :: Map stateKey [state]
paths = Map stateKey [state]
new_paths
}
new_queue_paths_M :: m (container, Map stateKey [state])
new_queue_paths_M =
((container, Map stateKey [state])
-> state -> (container, Map stateKey [state]))
-> (container, Map stateKey [state])
-> f state
-> (container, Map stateKey [state])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (container, Map stateKey [state])
-> state -> (container, Map stateKey [state])
update_queue_paths (SearchState container stateKey state -> container
forall container stateKey state.
SearchState container stateKey state -> container
queue SearchState container stateKey state
old, SearchState container stateKey state -> Map stateKey [state]
forall container stateKey state.
SearchState container stateKey state -> Map stateKey [state]
paths SearchState container stateKey state
old)
(f state -> (container, Map stateKey [state]))
-> m (f state) -> m (container, Map stateKey [state])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> state -> m (f state)
nextM (SearchState container stateKey state -> state
forall container stateKey state.
SearchState container stateKey state -> state
current SearchState container stateKey state
old)
update_queue_paths :: (container, Map stateKey [state])
-> state -> (container, Map stateKey [state])
update_queue_paths (container
old_queue, Map stateKey [state]
old_paths) state
st =
if state -> stateKey
mk_key state
st stateKey -> Set stateKey -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` SearchState container stateKey state -> Set stateKey
forall container stateKey state.
SearchState container stateKey state -> Set stateKey
visited SearchState container stateKey state
old
then (container
old_queue, Map stateKey [state]
old_paths)
else
case stateKey -> Map stateKey [state] -> Maybe [state]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (state -> stateKey
mk_key state
st) Map stateKey [state]
old_paths of
Just [state]
old_path ->
if [state] -> [state] -> Bool
better [state]
old_path (state
st state -> [state] -> [state]
forall a. a -> [a] -> [a]
: [state]
steps_so_far)
then (container
q', Map stateKey [state]
ps')
else (container
old_queue, Map stateKey [state]
old_paths)
Maybe [state]
Nothing -> (container
q', Map stateKey [state]
ps')
where
steps_so_far :: [state]
steps_so_far = SearchState container stateKey state -> Map stateKey [state]
forall container stateKey state.
SearchState container stateKey state -> Map stateKey [state]
paths SearchState container stateKey state
old Map stateKey [state] -> stateKey -> [state]
forall k a. Ord k => Map k a -> k -> a
Map.! state -> stateKey
mk_key (SearchState container stateKey state -> state
forall container stateKey state.
SearchState container stateKey state -> state
current SearchState container stateKey state
old)
q' :: container
q' = container -> Elem container -> container
forall container.
SearchContainer container =>
container -> Elem container -> container
push container
old_queue state
Elem container
st
ps' :: Map stateKey [state]
ps' = stateKey -> [state] -> Map stateKey [state] -> Map stateKey [state]
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (state -> stateKey
mk_key state
st) (state
st state -> [state] -> [state]
forall a. a -> [a] -> [a]
: [state]
steps_so_far) Map stateKey [state]
old_paths
generalizedSearchM ::
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state)
=> container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM :: container
-> (state -> stateKey)
-> ([state] -> [state] -> Bool)
-> (state -> m (f state))
-> (state -> m Bool)
-> state
-> m (Maybe [state])
generalizedSearchM container
empty state -> stateKey
mk_key [state] -> [state] -> Bool
better state -> m (f state)
nextM state -> m Bool
foundM state
initial = do
let initial_state :: SearchState container stateKey state
initial_state =
state
-> container
-> Set stateKey
-> Map stateKey [state]
-> SearchState container stateKey state
forall container stateKey state.
state
-> container
-> Set stateKey
-> Map stateKey [state]
-> SearchState container stateKey state
SearchState state
initial container
empty (stateKey -> Set stateKey
forall a. a -> Set a
Set.singleton (stateKey -> Set stateKey) -> stateKey -> Set stateKey
forall a b. (a -> b) -> a -> b
$ state -> stateKey
mk_key state
initial)
(stateKey -> [state] -> Map stateKey [state]
forall k a. k -> a -> Map k a
Map.singleton (state -> stateKey
mk_key state
initial) [])
Maybe (SearchState container stateKey state)
end_May <- (SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state)))
-> (SearchState container stateKey state -> m Bool)
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
forall (m :: * -> *) a.
Monad m =>
(a -> m (Maybe a)) -> (a -> m Bool) -> a -> m (Maybe a)
findIterateM (([state] -> [state] -> Bool)
-> (state -> stateKey)
-> (state -> m (f state))
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
forall (m :: * -> *) (f :: * -> *) container stateKey state.
(Monad m, Foldable f, SearchContainer container, Ord stateKey,
Elem container ~ state) =>
([state] -> [state] -> Bool)
-> (state -> stateKey)
-> (state -> m (f state))
-> SearchState container stateKey state
-> m (Maybe (SearchState container stateKey state))
nextSearchStateM [state] -> [state] -> Bool
better state -> stateKey
mk_key state -> m (f state)
nextM)
(state -> m Bool
foundM (state -> m Bool)
-> (SearchState container stateKey state -> state)
-> SearchState container stateKey state
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SearchState container stateKey state -> state
forall container stateKey state.
SearchState container stateKey state -> state
current) SearchState container stateKey state
initial_state
Maybe [state] -> m (Maybe [state])
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [state] -> m (Maybe [state]))
-> Maybe [state] -> m (Maybe [state])
forall a b. (a -> b) -> a -> b
$ (SearchState container stateKey state -> [state])
-> Maybe (SearchState container stateKey state) -> Maybe [state]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([state] -> [state]
forall a. [a] -> [a]
reverse ([state] -> [state])
-> (SearchState container stateKey state -> [state])
-> SearchState container stateKey state
-> [state]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SearchState container stateKey state -> [state]
get_steps) Maybe (SearchState container stateKey state)
end_May
where
get_steps :: SearchState container stateKey state -> [state]
get_steps SearchState container stateKey state
search_st = SearchState container stateKey state -> Map stateKey [state]
forall container stateKey state.
SearchState container stateKey state -> Map stateKey [state]
paths SearchState container stateKey state
search_st Map stateKey [state] -> stateKey -> [state]
forall k a. Ord k => Map k a -> k -> a
Map.! state -> stateKey
mk_key (SearchState container stateKey state -> state
forall container stateKey state.
SearchState container stateKey state -> state
current SearchState container stateKey state
search_st)
newtype LIFOHeap k a = LIFOHeap (Map.Map k [a])
emptyLIFOHeap :: LIFOHeap k a
emptyLIFOHeap :: LIFOHeap k a
emptyLIFOHeap = Map k [a] -> LIFOHeap k a
forall k a. Map k [a] -> LIFOHeap k a
LIFOHeap Map k [a]
forall k a. Map k a
Map.empty
class SearchContainer container where
type Elem container
pop :: container -> Maybe (Elem container, container)
push :: container -> Elem container -> container
instance SearchContainer (Seq.Seq a) where
type Elem (Seq.Seq a) = a
pop :: Seq a -> Maybe (Elem (Seq a), Seq a)
pop Seq a
s =
case Seq a -> ViewL a
forall a. Seq a -> ViewL a
Seq.viewl Seq a
s of
ViewL a
Seq.EmptyL -> Maybe (Elem (Seq a), Seq a)
forall a. Maybe a
Nothing
(a
x Seq.:< Seq a
xs) -> (a, Seq a) -> Maybe (a, Seq a)
forall a. a -> Maybe a
Just (a
x, Seq a
xs)
push :: Seq a -> Elem (Seq a) -> Seq a
push Seq a
s Elem (Seq a)
a = Seq a
s Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
Seq.|> a
Elem (Seq a)
a
instance SearchContainer [a] where
type Elem [a] = a
pop :: [a] -> Maybe (Elem [a], [a])
pop [a]
list =
case [a]
list of
[] -> Maybe (Elem [a], [a])
forall a. Maybe a
Nothing
(a
x : [a]
xs) -> (a, [a]) -> Maybe (a, [a])
forall a. a -> Maybe a
Just (a
x, [a]
xs)
push :: [a] -> Elem [a] -> [a]
push [a]
list Elem [a]
a = a
Elem [a]
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
list
instance Ord k => SearchContainer (LIFOHeap k a) where
type Elem (LIFOHeap k a) = (k, a)
pop :: LIFOHeap k a -> Maybe (Elem (LIFOHeap k a), LIFOHeap k a)
pop (LIFOHeap Map k [a]
inner)
| Map k [a] -> Bool
forall k a. Map k a -> Bool
Map.null Map k [a]
inner = Maybe (Elem (LIFOHeap k a), LIFOHeap k a)
forall a. Maybe a
Nothing
| Bool
otherwise = case Map k [a] -> (k, [a])
forall k a. Map k a -> (k, a)
Map.findMin Map k [a]
inner of
(k
k, [a
a]) -> ((k, a), LIFOHeap k a) -> Maybe ((k, a), LIFOHeap k a)
forall a. a -> Maybe a
Just ((k
k, a
a), Map k [a] -> LIFOHeap k a
forall k a. Map k [a] -> LIFOHeap k a
LIFOHeap (Map k [a] -> LIFOHeap k a) -> Map k [a] -> LIFOHeap k a
forall a b. (a -> b) -> a -> b
$ Map k [a] -> Map k [a]
forall k a. Map k a -> Map k a
Map.deleteMin Map k [a]
inner)
(k
k, a
a : [a]
_) -> ((k, a), LIFOHeap k a) -> Maybe ((k, a), LIFOHeap k a)
forall a. a -> Maybe a
Just ((k
k, a
a), Map k [a] -> LIFOHeap k a
forall k a. Map k [a] -> LIFOHeap k a
LIFOHeap (Map k [a] -> LIFOHeap k a) -> Map k [a] -> LIFOHeap k a
forall a b. (a -> b) -> a -> b
$ ([a] -> Maybe [a]) -> Map k [a] -> Map k [a]
forall a k. (a -> Maybe a) -> Map k a -> Map k a
Map.updateMin ([a] -> Maybe [a]
forall a. a -> Maybe a
Just ([a] -> Maybe [a]) -> ([a] -> [a]) -> [a] -> Maybe [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
tail) Map k [a]
inner)
(k
_, []) -> LIFOHeap k a -> Maybe (Elem (LIFOHeap k a), LIFOHeap k a)
forall container.
SearchContainer container =>
container -> Maybe (Elem container, container)
pop (Map k [a] -> LIFOHeap k a
forall k a. Map k [a] -> LIFOHeap k a
LIFOHeap (Map k [a] -> LIFOHeap k a) -> Map k [a] -> LIFOHeap k a
forall a b. (a -> b) -> a -> b
$ Map k [a] -> Map k [a]
forall k a. Map k a -> Map k a
Map.deleteMin Map k [a]
inner)
push :: LIFOHeap k a -> Elem (LIFOHeap k a) -> LIFOHeap k a
push (LIFOHeap Map k [a]
inner) (k, a) = Map k [a] -> LIFOHeap k a
forall k a. Map k [a] -> LIFOHeap k a
LIFOHeap (Map k [a] -> LIFOHeap k a) -> Map k [a] -> LIFOHeap k a
forall a b. (a -> b) -> a -> b
$ ([a] -> [a] -> [a]) -> k -> [a] -> Map k [a] -> Map k [a]
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) k
k [a
a] Map k [a]
inner
findIterateM :: Monad m => (a -> m (Maybe a)) -> (a -> m Bool) -> a -> m (Maybe a)
findIterateM :: (a -> m (Maybe a)) -> (a -> m Bool) -> a -> m (Maybe a)
findIterateM a -> m (Maybe a)
nextM a -> m Bool
foundM a
initial = do
Bool
found <- a -> m Bool
foundM a
initial
if Bool
found
then Maybe a -> m (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
Just a
initial
else a -> m (Maybe a)
nextM a
initial m (Maybe a) -> (Maybe a -> m (Maybe a)) -> m (Maybe a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m (Maybe a) -> (a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe a -> m (Maybe a)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing) ((a -> m (Maybe a)) -> (a -> m Bool) -> a -> m (Maybe a)
forall (m :: * -> *) a.
Monad m =>
(a -> m (Maybe a)) -> (a -> m Bool) -> a -> m (Maybe a)
findIterateM a -> m (Maybe a)
nextM a -> m Bool
foundM)
leastCostly :: Ord a => [(a, b)] -> [(a, b)] -> Bool
leastCostly :: [(a, b)] -> [(a, b)] -> Bool
leastCostly ((a
cost_a, b
_):[(a, b)]
_) ((a
cost_b, b
_):[(a, b)]
_) = a
cost_b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
cost_a
leastCostly [] [(a, b)]
_ = Bool
False
leastCostly [(a, b)]
_ [] = Bool
True
fmap2 :: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
fmap2 :: (a -> b) -> f1 (f2 a) -> f1 (f2 b)
fmap2 = (f2 a -> f2 b) -> f1 (f2 a) -> f1 (f2 b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((f2 a -> f2 b) -> f1 (f2 a) -> f1 (f2 b))
-> ((a -> b) -> f2 a -> f2 b) -> (a -> b) -> f1 (f2 a) -> f1 (f2 b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> f2 a -> f2 b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap