Haskellのリスト操作をOCamlに移植(3)

mzp2008-08-06

30分プログラム、その344。昨日に引き続き、http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.htmlの関数をOcamlに移植。これで最後。

使い方

# unzip [(1,2);(3,4)];;
- : int list * int list = ([1; 3], [2; 4])

ソースコード

let rec splitAt n xs =
  match n,xs with
      0,_  | _,[] ->
	[],xs
    | _,y::ys ->
	let p,q = 
	  splitAt (n-1) ys in
	  y::p,q

let rec takeWhile f =
  function
      x::xs when f x ->
	x :: takeWhile f xs
    | _ ->
	[]

let rec dropWhile f =
  function
      x::xs when f x ->
	dropWhile f xs
    | xs ->
	xs

let rec span f =
  function
      x::xs when f x -> 
	let ys,zs =
	  span f xs in
	  x::ys,zs
    | xs -> 
	[],xs

let break f =
  span (not $ f)

let rec zip_with f xs ys =
  match xs,ys with
      [],_ | _,[] ->
	[]
    | x::xs',y::ys' ->
	(f x y)::zip_with f xs' ys'

let rec zip_with3 f xs ys zs =
  match xs,ys,zs with
      [],_,_ | _,[],_ | _,_,[] ->
	[]
    | x::xs',y::ys',z::zs' ->
	(f x y z)::zip_with3 f xs' ys' zs'

let zip xs ys =
  zip_with (fun x y -> (x,y)) xs ys

let zip3 xs ys zs =
  zip_with3 (fun x y z -> (x,y,z)) xs ys zs

let unzip xs =
  List.fold_right (fun (x,y) (xs,ys) -> (x::xs,y::ys)) xs ([],[])

let unzip3 xs =
  List.fold_right (fun (x,y,z) (xs,ys,zs) -> (x::xs,y::ys,z::zs)) xs ([],[],[])