Skip to content

Commit

Permalink
Add throughZCurveFix and throughZCurveFix3
Browse files Browse the repository at this point in the history
  • Loading branch information
Bodigrim committed Dec 27, 2023
1 parent bef545d commit 018831d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
3 changes: 1 addition & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

* Add `HalfWord` and `ThirdWord` types,
change types of `toZCurve`, `fromZCurve`, `toZCurve3`, `fromZCurve3` accordingly.
* New module `Data.Chimera.Memoize` providing various
memoization combinators.
* Add `throughZCurveFix` and `throughZCurveFix3`.

# 0.3.4.0

Expand Down
48 changes: 48 additions & 0 deletions src/Data/Chimera/ContinuousMapping.hs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ module Data.Chimera.ContinuousMapping (
HalfWord,
toZCurve,
fromZCurve,
throughZCurveFix,
ThirdWord,
toZCurve3,
fromZCurve3,
throughZCurveFix3,
) where

import Data.Bifunctor
Expand Down Expand Up @@ -160,6 +162,28 @@ toZCurve x y = part1by1 y `shiftL` 1 .|. part1by1 x
fromZCurve :: Word -> (HalfWord, HalfWord)
fromZCurve z = (compact1by1 z, compact1by1 (z `shiftR` 1))

-- | Convert a function of two 'HalfWord's to a function of one 'Word'.
contramapFromZCurve
:: (HalfWord -> HalfWord -> a)
-> (Word -> a)
contramapFromZCurve f = uncurry f . fromZCurve

-- | Convert a function of one 'Word' to a function of two 'HalfWord's.
contramapToZCurve
:: (Word -> a)
-> (HalfWord -> HalfWord -> a)
contramapToZCurve f = (f .) . toZCurve

-- | For an input function @f@ return function @g@ such that
-- 'fix' @f@ = throughZCurve ('fix' @g@).
--
-- @since 0.4.0.0
throughZCurveFix
:: ((HalfWord -> HalfWord -> a) -> (HalfWord -> HalfWord -> a))
-> (Word -> a)
-> (Word -> a)
throughZCurveFix f = contramapFromZCurve . f . contramapToZCurve

-- | 21 bits on 64-bit architecture, 10 bits on 32-bit architecture.
--
-- To create a value of type 'ThirdWord' use 'fromIntegral'.
Expand Down Expand Up @@ -246,6 +270,30 @@ toZCurve3 x y z = part1by2 z `shiftL` 2 .|. part1by2 y `shiftL` 1 .|. part1by2 x
fromZCurve3 :: Word -> (ThirdWord, ThirdWord, ThirdWord)
fromZCurve3 z = (compact1by2 z, compact1by2 (z `shiftR` 1), compact1by2 (z `shiftR` 2))

-- | Convert a function of two 'HalfWord's to a function of one 'Word'.
contramapFromZCurve3
:: (ThirdWord -> ThirdWord -> ThirdWord -> a)
-> (Word -> a)
contramapFromZCurve3 f = uncurry3 f . fromZCurve3
where
uncurry3 func (a, b, c) = func a b c

-- | Convert a function of one 'Word' to a function of two 'HalfWord's.
contramapToZCurve3
:: (Word -> a)
-> (ThirdWord -> ThirdWord -> ThirdWord -> a)
contramapToZCurve3 f = ((f .) .) . toZCurve3

-- | For an input function @f@ return function @g@ such that
-- 'fix' @f@ = throughZCurve ('fix' @g@).
--
-- @since 0.4.0.0
throughZCurveFix3
:: ((ThirdWord -> ThirdWord -> ThirdWord -> a) -> (ThirdWord -> ThirdWord -> ThirdWord -> a))
-> (Word -> a)
-> (Word -> a)
throughZCurveFix3 f = contramapFromZCurve3 . f . contramapToZCurve3

-- Inspired by https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
part1by1 :: HalfWord -> Word
part1by1 x = fromIntegral (x5 :: Word64)
Expand Down

0 comments on commit 018831d

Please sign in to comment.