Вы не хотите сравнивать L=nil
, так как это работает только для списков типа которые сопоставимы (например, а не списки функций). Скорее, вам нужен образец, который предлагает Кевин Джонсон;
fun length [] = 0
| length (x::xs) = 1 + length xs
Или используя хвост рекурсию:
fun length xs =
let fun len [] n = n
| len (x::xs) n = len xs (1+n)
in len xs 0 end
В отличие от length : 'a list -> int
, эта функция имеет тип 'a list list -> int
.
Объединенная длина всех подсписок может быть достигнута несколькими способами. Например.
fun length2 xss = List.foldl op+ 0 (List.concat xss)
Но ответ Кевин также использует, там действительно нет смысла строить новый список с List.concat xss
, когда все мы делаем, это уничтожить его снова мгновений спустя. Так бесстыдно отрываться свое решение:
fun length2 xss = List.foldl (fn (xs, sum) => length xs + sum) 0 xss
, который, вероятно, является самым читаемым способ выразить эту функцию, тоже, но если вы должны были попытаться code golf эта функция очень короткий, можно также переписать внутреннее замыкание, используя выше -порядок функции:
fun curry f x y = f (x, y)
fun uncurry f (x, y) = f x y
fun length2 xss = List.foldl (uncurry (curry op+ o length)) 0 xss
Мне потребовалось несколько минут, чтобы понять, что вы делаете с этим карри/некрасивым.Это очень умно. –
Было бы более умно, если бы по умолчанию были 'foldl' и' op + ', и не было [Value Restriction] (http://users.cis.fiu.edu/~smithg/cop4555/valrestr.html). Тогда это будет 'val length2 = foldl (op + o length) 0'! –
Я определенно столкнулся с этим ограничением стоимости пару раз, когда играю с этим. В Haskell вы можете (я думаю) сделать все это в стиле без ограничений, но SML затрудняет накопление с помощью 'o' –