I've got a data type
G
, which have got field _repr :: Data.Graph.Inductive.Gr String String
. The normal way, when adding new node into Gr
graph, we have to provide an LNode a
object, which basically is defined as a tuple of (Int, a)
, where Int is the nodes index in Graph - see the example function add
below.
I want to implement a function addx
, which will compute the index automatically (for example by using Data.Graph.Inductive.newNodes
function). I want the addx
to have signature of addx :: String -> G -> Int
and this function will compute new free index, modify the graph G and return this computed index. Is it possible in Haskell to create such function (which will modify an existing object - G
in this case) - by using lenses or something like that?
I have seen, that Haskell lens is defined like lens :: (a -> c) -> (a -> d -> b) -> Lens a b c d
and lens is basically a "getter" and "setter", so its signature allows for different types of getter output (c
), setter value (d
) and setter output (b
).
import qualified Data.Graph.Inductive as DG
data G = G { _repr :: DG.Gr String String, _name::String} deriving ( Show )
empty :: G
empty = G DG.empty ""
add :: DG.LNode String -> G -> G
add node g = g{_repr = DG.insNode node $ _repr g}
-- is it possible to define it?
addx :: String -> G -> Int
addx name g = undefined
main :: IO ()
main = do
let g = add (1, "test2")
$ add (0, "test1")
$ empty
n1 = addx "test2" g
g2 = DG.insEdge(n1,0)
$ DG.insEdge(0,1)
print $ g