Skip to content
This repository was archived by the owner on Mar 25, 2021. It is now read-only.

Commit 6787600

Browse files
authored
Deriving Show (#5)
* Initial work on deriving Show * Add test for Show * Remove import * Travis etc.
1 parent bf35014 commit 6787600

File tree

8 files changed

+167
-14
lines changed

8 files changed

+167
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
/output/
55
/.psci*
66
/src/.webpack.js
7+
.psc-ide-port

.jscsrc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"preset": "grunt",
3+
"disallowSpacesInFunctionExpression": null,
4+
"requireSpacesInFunctionExpression": {
5+
"beforeOpeningRoundBrace": true,
6+
"beforeOpeningCurlyBrace": true
7+
},
8+
"disallowSpacesInAnonymousFunctionExpression": null,
9+
"requireSpacesInAnonymousFunctionExpression": {
10+
"beforeOpeningRoundBrace": true,
11+
"beforeOpeningCurlyBrace": true
12+
},
13+
"disallowSpacesInsideObjectBrackets": null,
14+
"requireSpacesInsideObjectBrackets": "all",
15+
"validateQuoteMarks": "\"",
16+
"requireCurlyBraces": null
17+
}

.jshintrc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"bitwise": true,
3+
"eqeqeq": true,
4+
"forin": true,
5+
"freeze": true,
6+
"funcscope": true,
7+
"futurehostile": true,
8+
"strict": "global",
9+
"latedef": true,
10+
"maxparams": 1,
11+
"noarg": true,
12+
"nocomma": true,
13+
"nonew": true,
14+
"notypeof": true,
15+
"singleGroups": true,
16+
"undef": true,
17+
"unused": true,
18+
"eqnull": true,
19+
"predef": ["exports"]
20+
}

.travis.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
language: node_js
2+
dist: trusty
3+
sudo: required
4+
node_js: 6
5+
env:
6+
- PATH=$HOME/purescript:$PATH
7+
install:
8+
- TAG=$(wget -q -O - https://github.com/purescript/purescript/releases/latest --server-response --max-redirect 0 2>&1 | sed -n -e 's/.*Location:.*tag\///p')
9+
- wget -O $HOME/purescript.tar.gz https://github.com/purescript/purescript/releases/download/$TAG/linux64.tar.gz
10+
- tar -xvf $HOME/purescript.tar.gz -C $HOME/
11+
- chmod a+x $HOME/purescript
12+
- npm install -g bower
13+
- npm install
14+
script:
15+
- bower install --production
16+
- npm run -s build
17+
- bower install
18+
- npm -s test
19+
after_success:
20+
- >-
21+
test $TRAVIS_TAG &&
22+
echo $GITHUB_TOKEN | pulp login &&
23+
echo y | pulp publish --no-push

bower.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
},
1414
"dependencies": {
1515
"purescript-prelude": "^2.0.0",
16-
"purescript-monoid": "^2.0.0"
16+
"purescript-monoid": "^2.0.0",
17+
"purescript-symbols": "^2.0.0",
18+
"purescript-foldable-traversable": "^2.0.0"
19+
},
20+
"devDependencies": {
21+
"purescript-console": "^2.0.0"
1722
}
1823
}

package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"clean": "rimraf output && rimraf .pulp-cache",
5+
"build": "jshint src && jscs src && psa \"src/**/*.purs\" \"bower_components/purescript-*/src/**/*.purs\" --censor-lib --strict",
6+
"test": "psc \"src/**/*.purs\" \"bower_components/purescript-*/src/**/*.purs\" \"test/**/*.purs\" && psc-bundle \"output/**/*.js\" --module Test.Main --main Test.Main | node"
7+
},
8+
"devDependencies": {
9+
"jscs": "^2.8.0",
10+
"jshint": "^2.9.1",
11+
"pulp": "^8.2.0",
12+
"purescript-psa": "^0.3.8",
13+
"rimraf": "^2.5.0"
14+
}
15+
}

src/Data/Generic/Rep/Show.purs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
module Data.Generic.Rep.Show
2+
( class GenericShow
3+
, genericShow'
4+
, genericShow
5+
, class GenericShowArgs
6+
, genericShowArgs
7+
, class GenericShowFields
8+
, genericShowFields
9+
) where
10+
11+
import Prelude (class Show, show, (<>))
12+
import Data.Foldable (intercalate)
13+
import Data.Generic.Rep
14+
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
15+
16+
class GenericShow a where
17+
genericShow' :: a -> String
18+
19+
class GenericShowArgs a where
20+
genericShowArgs :: a -> Array String
21+
22+
class GenericShowFields a where
23+
genericShowFields :: a -> Array String
24+
25+
instance genericShowNoConstructors :: GenericShow NoConstructors where
26+
genericShow' a = genericShow' a
27+
28+
instance genericShowArgsNoArguments :: GenericShowArgs NoArguments where
29+
genericShowArgs _ = []
30+
31+
instance genericShowSum :: (GenericShow a, GenericShow b) => GenericShow (Sum a b) where
32+
genericShow' (Inl a) = genericShow' a
33+
genericShow' (Inr b) = genericShow' b
34+
35+
instance genericShowArgsProduct
36+
:: (GenericShowArgs a, GenericShowArgs b)
37+
=> GenericShowArgs (Product a b) where
38+
genericShowArgs (Product a b) = genericShowArgs a <> genericShowArgs b
39+
40+
instance genericShowFieldsProduct
41+
:: (GenericShowFields a, GenericShowFields b)
42+
=> GenericShowFields (Product a b) where
43+
genericShowFields (Product a b) = genericShowFields a <> genericShowFields b
44+
45+
instance genericShowConstructor
46+
:: (GenericShowArgs a, IsSymbol name)
47+
=> GenericShow (Constructor name a) where
48+
genericShow' (Constructor a) =
49+
case genericShowArgs a of
50+
[] -> ctor
51+
args -> "(" <> intercalate " " ([ctor] <> args) <> ")"
52+
where
53+
ctor :: String
54+
ctor = reflectSymbol (SProxy :: SProxy name)
55+
56+
instance genericShowArgsArgument :: Show a => GenericShowArgs (Argument a) where
57+
genericShowArgs (Argument a) = [show a]
58+
59+
instance genericShowArgsRec :: GenericShowFields a => GenericShowArgs (Rec a) where
60+
genericShowArgs (Rec a) = ["{ " <> intercalate ", " (genericShowFields a) <> " }"]
61+
62+
instance genericShowFieldsField
63+
:: (Show a, IsSymbol name)
64+
=> GenericShowFields (Field name a) where
65+
genericShowFields (Field a) =
66+
[reflectSymbol (SProxy :: SProxy name) <> ": " <> show a]
67+
68+
-- | A `Generic` implementation of the `show` member from the `Show` type class.
69+
genericShow :: forall a rep. (Generic a rep, GenericShow rep) => a -> String
70+
genericShow x = genericShow' (from x)

test/Main.purs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,30 @@ import Control.Monad.Eff.Console (CONSOLE, logShow)
66
import Data.Generic.Rep as G
77
import Data.Generic.Rep.Eq as GEq
88
import Data.Generic.Rep.Ord as GOrd
9+
import Data.Generic.Rep.Show as GShow
910

10-
data List a = Nil | Cons a (List a)
11+
data List a = Nil | Cons { head :: a, tail :: List a }
1112

12-
instance genericList :: G.Generic (List a)
13-
(G.Sum (G.Constructor "Nil" G.NoArguments)
14-
(G.Constructor "Cons" (G.Product (G.Argument a)
15-
(G.Argument (List a))))) where
16-
to (G.Inl (G.Constructor G.NoArguments)) = Nil
17-
to (G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs)))) = Cons x xs
18-
from Nil = G.Inl (G.Constructor G.NoArguments)
19-
from (Cons x xs) = G.Inr (G.Constructor (G.Product (G.Argument x) (G.Argument xs)))
13+
cons :: forall a. a -> List a -> List a
14+
cons head tail = Cons { head, tail }
15+
16+
derive instance genericList :: G.Generic (List a) _
2017

2118
instance eqList :: Eq a => Eq (List a) where
2219
eq x y = GEq.genericEq x y
2320

2421
instance ordList :: Ord a => Ord (List a) where
2522
compare x y = GOrd.genericCompare x y
2623

24+
instance showList :: Show a => Show (List a) where
25+
show x = GShow.genericShow x
26+
2727
main :: Eff (console :: CONSOLE) Unit
2828
main = do
29-
logShow (Cons 1 (Cons 2 Nil) == Cons 1 (Cons 2 Nil))
30-
logShow (Cons 1 (Cons 2 Nil) == Cons 1 Nil)
29+
logShow (cons 1 (cons 2 Nil))
30+
31+
logShow (cons 1 (cons 2 Nil) == cons 1 (cons 2 Nil))
32+
logShow (cons 1 (cons 2 Nil) == cons 1 Nil)
3133

32-
logShow (Cons 1 (Cons 2 Nil) `compare` Cons 1 (Cons 2 Nil))
33-
logShow (Cons 1 (Cons 2 Nil) `compare` Cons 1 Nil)
34+
logShow (cons 1 (cons 2 Nil) `compare` cons 1 (cons 2 Nil))
35+
logShow (cons 1 (cons 2 Nil) `compare` cons 1 Nil)

0 commit comments

Comments
 (0)