Skip to content

Instantly share code, notes, and snippets.

@lierdakil
Last active April 11, 2017 20:22
Show Gist options
  • Select an option

  • Save lierdakil/4ce14eb8970975764b154561979d0a9f to your computer and use it in GitHub Desktop.

Select an option

Save lierdakil/4ce14eb8970975764b154561979d0a9f to your computer and use it in GitHub Desktop.
A small example of using loop from Control.Arrow
{-# LANGUAGE FlexibleContexts #-}
module ArrowTest where
import Control.Arrow
import Test.QuickCheck
f, g :: Floating a => [a] -> [a]
f = loop go
where
-- для вычисления непосредственно нормы
-- используется acc,
-- который взят с первой итерации.
-- Но он в свою очередь вычисляется
-- как 0 + xₙ² + ... + x₁²
-- через acc', который потом скарливается
-- в теле loop обратно на вход
go (x:xs, acc) =
let (xs', acc') = go (xs, acc)
in (x / sqrt acc : xs', acc' + x*x)
go ([], _) = ([], 0)
g t = map (/ sqrt norm2) t
where
norm2 = foldl (\acc x -> acc + x*x) 0 t
prop :: [Double] -> Bool
prop t = all eqNaN $ zip (f t) (g t)
where
eqNaN (x, y)
| isNaN x && isNaN y = True
| otherwise = abs (x - y) < epsilon
epsilon = go 1
where go x | 1 + x == 1 = x
| otherwise = x/2
test :: IO ()
test = quickCheckWith stdArgs { maxSuccess = 50000 } prop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment