···11+# Revision history for merkle-basic-haskell
22+33+## 0.1.0.0 -- YYYY-mm-dd
44+55+* First version. Released on an unsuspecting world.
+44
app/Main.hs
···11+module Main where
22+33+import Data.Bifunctor (Bifunctor (bimap))
44+import Data.Bits (Bits (shiftR), (.|.))
55+import Data.Foldable (Foldable (foldr'), foldl')
66+import Data.Hashable (Hashable, hash)
77+import qualified Data.List.NonEmpty as NE
88+99+type Hash = Int
1010+1111+-- this can be also rep as a Map<a, Hash>
1212+data Merkle a = Merkle Hash a deriving (Show)
1313+1414+unHash :: Merkle a -> Hash
1515+unHash (Merkle h _) = h
1616+1717+def :: Monoid a => [a] -> a
1818+def = mempty
1919+2020+nextHighestPowerOfTwoSmallerThan :: (Num a, Bits a) => a -> a
2121+nextHighestPowerOfTwoSmallerThan n = (1 + foldl' go (n -1) [1, 2, 4, 8, 16, 32]) `shiftR` 1
2222+ where
2323+ go m i = m .|. m `shiftR` i
2424+2525+merkleTreeHash :: (Hashable a, Monoid a) => [a] -> NE.NonEmpty (Merkle a)
2626+merkleTreeHash xs@[] = return $ Merkle (hash $ def xs) mempty
2727+merkleTreeHash [x] = return $ Merkle (hash x) x
2828+merkleTreeHash xs =
2929+ let k = nextHighestPowerOfTwoSmallerThan $ length xs
3030+ (left, right) = bimap merkleTreeHash merkleTreeHash $ splitAt k xs
3131+ in left <> right
3232+3333+getMerkle :: (Hashable a, Monoid a, Eq a) => a -> [a] -> Maybe (Merkle a)
3434+getMerkle x = fmap NE.head . NE.nonEmpty . NE.dropWhile (\(Merkle _ a) -> a /= x) . merkleTreeHash
3535+3636+getHash :: (Hashable a, Monoid a, Eq a) => a -> [a] -> Maybe Hash
3737+getHash x xs = unHash <$> getMerkle x xs
3838+3939+auditPath :: (Hashable a) => Int -> [a] -> Maybe [Hash]
4040+auditPath x xs | x > length xs = Nothing
4141+auditPath x xs = error "todo"
4242+4343+main :: IO ()
4444+main = putStrLn "Hello, Haskell!"
+35
merkle-basic-haskell.cabal
···11+cabal-version: 2.4
22+name: merkle-basic-haskell
33+version: 0.1.0.0
44+55+-- A short (one-line) description of the package.
66+-- synopsis:
77+88+-- A longer description of the package.
99+-- description:
1010+1111+-- A URL where users can report bugs.
1212+-- bug-reports:
1313+1414+-- The license under which the package is released.
1515+-- license:
1616+author: Kaushik Chakraborty
1717+maintainer: git@kaushikc.org
1818+1919+-- A copyright notice.
2020+-- copyright:
2121+-- category:
2222+extra-source-files: CHANGELOG.md
2323+2424+executable merkle-basic-haskell
2525+ main-is: Main.hs
2626+2727+ -- Modules included in this executable, other than Main.
2828+ -- other-modules:
2929+3030+ -- LANGUAGE extensions used by modules in this package.
3131+ -- other-extensions:
3232+ build-depends: base ^>=4.14.3.0,
3333+ hashable >= 1.3.0
3434+ hs-source-dirs: app
3535+ default-language: Haskell2010