Я не потрудился бы искать материал ASP.NET конкретно (вероятно, не найдет никого так или иначе). Нахождение хорошей темы CSS легко может использоваться в ASP.NET.
Вот некоторые сайты, которые я люблю за совершенство CSS:
http://www.freecsstemplates.org/
http://www.oswd.org/
http://www.openwebdesign.org/
http://www.styleshout.com/
http://www.freelayouts.com/
Вам просто нужно передать среднее значение по стеку с возвращаемым значением:
let foo ls =
let rec foo xs sumAcc lenAcc = match xs with
| x::xs -> let avg,s = foo xs (x + sumAcc) (1 + lenAcc) in
if x < avg then (avg,s) else (avg,s+1)
| [] -> (sumAcc / lenAcc),0
in
let avg,res = foo ls 0 0 in
res
Вот еще один вариант:
let foo =
let rec helper sum ct getCt = function
| x::xs ->
helper (sum+x) (ct+1) (fun avg -> getCt(avg) + (if avg <= x then 1 else 0)) xs
| [] -> getCt(sum/ct)
helper 0 0 (fun avg -> 0)
Чтобы прояснить, что здесь происходит, я опишу параметры для вспомогательной функции:
getCt
, чтобы определить, сколько элементов было больше, чем это. getCt
должна вызывать предыдущую функцию getCt
, чтобы увидеть, сколько элементов до этого больше среднего, а затем увеличивать эту сумму, если этот элемент также был больше. Также возможно создать модифицированную версию, которая использует только хвостовые вызовы, поэтому это не вызовет переполнения стека даже для списков произвольного размера. Для этого нашей функции getCt
теперь нужен параметр аккумулятора, представляющий текущий счетчик:
let foo =
let rec helper sum ct getCt = function
| x::xs ->
helper (sum+x) (ct+1) (fun avg n -> getCt avg (if avg <= x then n+1 else n)) xs
| [] -> getCt (sum/ct) 0
helper 0 0 (fun avg n -> n)
Ленивое вычисление Haskell действительно блестит в «завязывании узла»:
avgList t = let (final, sum, count) = go t 0 0 0
avg = sum `div` count
go [] finalA sumA countA = (finalA, sumA, countA)
go (x:xs) finalA sumA countA = go xs (x' + finalA) (sumA + x) (countA + 1)
where x' = if x >= avg then 1 else 0
in final