関数型言語への道

Haskellチュートリアルをやっているのですが理解度チェックのため、練習問題をHaskellNemerle両方で解きながら進めてます。

using System;

variant List [T] {
    | Nil
    | Cons { value : T ; next : List [T]; }
}

def show (l) {
    def iter (_) {
        | List.Nil => ()
        | List.Cons (x, List.Nil) => Console.Write ($"$x") 
        | List.Cons (x, xs) => Console.Write ($"$x,"); iter (xs)
    }
    Console.Write ("["); iter (l); Console.WriteLine ("]");
}

def length (_) {
    | List.Nil => 0
    | List.Cons (_, xs) => 1 + length (xs)
}

def head (_) {
    | List.Cons (x, _) => x 
    | _ => throw ArgumentException ()
}

def tail (_) {
    | List.Cons (_, xs) => xs
    | _ => throw ArgumentException ()
}

def foldl (_) {
    | (List.Cons (x, List.Nil), acc, fn) => fn (acc, x)
    | (List.Cons (x, xs), acc, fn) => foldl (xs, fn (acc, x), fn)
    | _ => throw ArgumentException ()
}

def foldr (_) {
    | (List.Cons (x, List.Nil), acc, fn) => fn (x, acc)
    | (List.Cons (x, xs), acc, fn) => fn (x, foldr (xs, acc, fn)) 
    | _ => throw ArgumentException ()
}

def l = List.Cons (10, List.Cons (20, List.Cons (30, List.Nil ())));

Console.WriteLine (length (l));
Console.WriteLine (head (l));
show (tail (l));
Console.WriteLine (foldl (l, 0, _ + _));
Console.WriteLine (foldr (l, 1, _ * _));

/*
3
10
[20,30]
60
6000
 */

関数型言語を学べば、それっぽく書けるものですね(笑)。