eval
uated to get some effect. Furthermore, there are typing issues, so adaptations are needed. The first function, compose
, is easy enough:
let compose p1 p2 = fun x -> p1 (p2 x)
Next, I defined a data type to represent list operations:
type ListOp = Car | Cdr | Compose of ListOp * ListOp | Error
So it's easy to define
car_cdr
, but it doesn't return a list to evaluate, rather a ListOp
object. Also, because of typing it was easier to include a variant Error
of type ListOp
and eliminate parameter errval
.
let rec car_cdr s slist =
match slist with
[] -> Error
| s1 :: rslist when s1 = s -> Car
| _ :: rslist -> Compose (car_cdr s rslist, Cdr)
Thus we get
> car_cdr "c" ["a"; "b"; "c"];;
val it : ListOp = Compose (Compose (Car,Cdr),Cdr)
So we have a description of the necessary list operations, but it's not directly executable as in Scheme. So we need a function to execute the list operations returned on a list, and this is
run_listop
let rec run_listop op lst =
match op with
Car -> List.hd lst
| Compose (c1, Cdr) -> run_listop c1 (List.tl lst)
| _ -> failwith "can't do"
The case that leads to an exception is to find a single
Cdr
without a previous Car
. This is a good indication that the type was not designed properly, but we will not bother with this here. Function car_cdr2
doesn't need explicit Compose
operations, and returns a list of list operations that must be applied in succession.
let car_cdr2 s slist errval =
let rec loop lst =
match lst with
[] -> []
| l :: rlst when s = l -> [Car]
| _ :: rlst -> Cdr :: (loop rlst) in
List.rev (loop slist)
It's quite easy to define a function to execute these
ListOp
lists, but not that interesting at this point.
No comments:
Post a Comment