Skip to content

Commit 0c0b216

Browse files
authored
Merge pull request #10 from garyb/fix
Add `fix`
2 parents 5e32e0e + 00bcfac commit 0c0b216

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

src/Data/Codec/Argonaut.purs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module Data.Codec.Argonaut
2020
, prop
2121
, record
2222
, recordProp
23+
, fix
2324
, module Exports
2425
) where
2526

@@ -238,3 +239,10 @@ jsonPrimCodec
238239
JsonCodec a
239240
jsonPrimCodec ty f =
240241
basicCodec (maybe (Left (TypeMismatch ty)) pure <<< f)
242+
243+
-- | Helper function for defining recursive codecs.
244+
fix a. (JsonCodec a JsonCodec a) JsonCodec a
245+
fix f =
246+
basicCodec
247+
(\x → decode (f (fix f)) x)
248+
(\x → encode (f (fix f)) x)

src/Data/Codec/Argonaut/Common.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module Data.Codec.Argonaut.Common
66
import Prelude hiding (map)
77

88
import Data.Array as A
9-
import Data.Codec.Argonaut (JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, decode, encode, index, indexedArray, int, jarray, jobject, json, null, number, object, printJsonDecodeError, prop, record, recordProp, string, (<~<), (~))
9+
import Data.Codec.Argonaut (JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, decode, encode, fix, index, indexedArray, int, jarray, jobject, json, null, number, object, printJsonDecodeError, prop, record, recordProp, string, (<~<), (~))
1010
import Data.Codec.Argonaut.Sum (taggedSum)
1111
import Data.Either (Either(..))
1212
import Data.Functor as F

src/Data/Codec/Argonaut/Compat.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Prelude
1010
import Data.Argonaut.Core as J
1111
import Data.Bifunctor as BF
1212
import Data.Codec (basicCodec, mapCodec)
13-
import Data.Codec.Argonaut (JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, decode, encode, index, indexedArray, int, jarray, jobject, json, null, number, object, printJsonDecodeError, prop, record, recordProp, string, (<~<), (~))
13+
import Data.Codec.Argonaut (JIndexedCodec, JPropCodec, JsonCodec, JsonDecodeError(..), array, boolean, char, decode, encode, fix, index, indexedArray, int, jarray, jobject, json, null, number, object, printJsonDecodeError, prop, record, recordProp, string, (<~<), (~))
1414
import Data.Codec.Argonaut.Common (either, list, map, tuple) as Common
1515
import Data.Either (Either)
1616
import Data.Functor as F

test/Test/Prim.purs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ import Prelude
44

55
import Control.Monad.Eff.Console (log)
66
import Control.Monad.Gen as Gen
7+
import Control.Monad.Gen.Common as GenC
78
import Data.Argonaut.Core as J
89
import Data.Argonaut.Gen (genJson)
910
import Data.Char.Gen (genAsciiChar)
1011
import Data.Codec.Argonaut.Common ((~))
1112
import Data.Codec.Argonaut.Common as JA
12-
import Data.String.Gen (genAsciiString)
13+
import Data.Generic.Rep (class Generic)
14+
import Data.Generic.Rep.Show (genericShow)
15+
import Data.Maybe (Maybe(..))
16+
import Data.Newtype (class Newtype, unwrap, wrap)
17+
import Data.Profunctor (dimap)
1318
import Data.StrMap.Gen (genStrMap)
19+
import Data.String.Gen (genAsciiString)
1420
import Data.Symbol (SProxy(..))
1521
import Test.QuickCheck (QC, Result, quickCheck)
1622
import Test.QuickCheck.Gen (Gen)
@@ -48,6 +54,9 @@ main = do
4854
log "Checking record codec"
4955
quickCheck (propTestRecord codecRecord)
5056

57+
log "Checking fixed-point codec"
58+
quickCheck propFix
59+
5160
propNull Gen Result
5261
propNull = propCodec (pure J.jNull) JA.null
5362

@@ -102,3 +111,23 @@ propTestRecord = propCodec' checkEq print genRecord
102111
checkEq r1 r2 = r1.tag == r2.tag && r1.x == r2.x && r1.y == r2.y
103112
print { tag, x, y } =
104113
"{ tag: " <> show tag <> ", x: " <> show x <> ", y: " <> show y <> " }"
114+
115+
newtype FixTest = FixTest (Maybe FixTest)
116+
117+
derive instance newtypeFixTestNewtype FixTest _
118+
derive instance genericFixTestGeneric FixTest _
119+
instance eqFixTestEq FixTest where eq (FixTest x) (FixTest y) = x == y
120+
instance showFixTestShow FixTest where show x = genericShow x
121+
122+
genFixTest Gen FixTest
123+
genFixTest = Gen.sized \n →
124+
if n <= 1
125+
then pure $ FixTest Nothing
126+
else FixTest <$> Gen.resize (_ - 1) (GenC.genMaybe genFixTest)
127+
128+
codecFixTest JA.JsonCodec FixTest
129+
codecFixTest = JA.fix \codec →
130+
dimap unwrap wrap (JA.maybe codec)
131+
132+
propFix Gen Result
133+
propFix = propCodec genFixTest codecFixTest

0 commit comments

Comments
 (0)