Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying a function to a custom type in F#

On my journey to learning F#, I've run into a problem I cant solve. I have defined a custom type:

type BinTree = 
  | Node of int * BinTree * BinTree
  | Empty

I have made a function which takes a tree, traverses it, and adds the elements it visits to a list, and returns it:

let rec inOrder tree = 
 seq{
 match tree with
  | Node (data, left, right) ->
   yield! inOrder left
   yield  data;
   yield! inOrder right
  | Empty -> ()
 }
 |> Seq.to_list;

Now I want to create a function, similar to this, which takes a tree and a function, traverses it and applies a function to each node, then returns the tree:

mapInOrder : ('a -> 'b) -> 'a BinTree -> 'b BinTree

This seems easy, and it probably is! But I'm not sure how to return the tree. I've tried this:

let rec mapInOrder f tree = 
 match tree with
 | Node(data, left, right) ->
  mapInOrder f left
  Node(f(data), left, right)
  mapInOrder f right
 | Empty -> ()

but this returns a unit. I havent worked with custom types before, so I'm probably missing something there!

like image 387
Frederik Wordenskjold Avatar asked Mar 07 '26 23:03

Frederik Wordenskjold


1 Answers

Try this:

let rec mapInOrder f = function
  | Node(a,l,r) ->
      let newL = mapInOrder f l
      let b = f a
      let newR = mapInOrder f r
      Node(b,newL,newR)
  | Empty -> Empty

If the function is side-effect free, then traversal order is unimportant and you can instead write:

let rec map f = function
  | Node(a,l,r) -> Node(f a, map f l, map f r)
  | Empty -> Empty
like image 63
kvb Avatar answered Mar 10 '26 03:03

kvb