Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
F
fp_scala
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
study-notes
fp_scala
Commits
0f38e1e7
Commit
0f38e1e7
authored
Apr 05, 2017
by
Haochen Xie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update ch10/Monoids.scala
parent
43988716
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
43 additions
and
5 deletions
+43
-5
build.sbt
build.sbt
+2
-2
Monoids.scala
src/main/scala/name/haochenxie/fpscala/ch10/Monoids.scala
+41
-3
No files found.
build.sbt
View file @
0f38e1e7
...
...
@@ -4,10 +4,10 @@ version := "1.0"
scalaVersion
:=
"2.12.1"
libraryDependencies
+=
"org.scalacheck"
%%
"scalacheck"
%
"1.13.4"
%
"test"
libraryDependencies
+=
"org.scalacheck"
%%
"scalacheck"
%
"1.13.4"
libraryDependencies
+=
"org.scalactic"
%%
"scalactic"
%
"3.0.1"
libraryDependencies
+=
"org.scalatest"
%%
"scalatest"
%
"3.0.1"
%
"test"
libraryDependencies
+=
"org.scalatest"
%%
"scalatest"
%
"3.0.1"
libraryDependencies
+=
"junit"
%
"junit"
%
"4.12"
%
"test"
libraryDependencies
+=
"commons-codec"
%
"commons-codec"
%
"1.10"
...
...
src/main/scala/name/haochenxie/fpscala/ch10/Monoids.scala
View file @
0f38e1e7
package
name.haochenxie.fpscala.ch10
import
scala.collection.mutable.ArrayBuffer
import
org.scalacheck.Prop.forAll
import
org.scalacheck._
trait
Monoid
[
A
]
{
def
op
(
a1
:
A
,
a2
:
A
)
:
A
...
...
@@ -9,16 +10,29 @@ trait Monoid[A] {
object
Monoids
{
def
monoidSpec
[
A
](
propName
:
String
,
m
:
Monoid
[
A
])(
implicit
arb
:
Arbitrary
[
A
])
:
Properties
=
new
Properties
(
propName
)
{
property
(
"assoc"
)
=
forAll
{
(
a
:
A
,
b
:
A
,
c
:
A
)
=>
m
.
op
(
m
.
op
(
a
,
b
),
c
)
==
m
.
op
(
a
,
m
.
op
(
b
,
c
))
}
property
(
"unit"
)
=
forAll
{
(
a
:
A
)
=>
m
.
op
(
m
.
zero
,
a
)
==
a
&&
a
==
m
.
op
(
a
,
m
.
zero
)
}
}
val
stringMonoid
=
new
Monoid
[
String
]
{
override
def
op
(
a1
:
String
,
a2
:
String
)
:
String
=
a1
+
a2
override
val
zero
:
String
=
""
}
val
stringMonoidSpec
=
monoidSpec
(
"StringMonoidSpec"
,
stringMonoid
)
def
listMonoid
[
A
]
=
new
Monoid
[
List
[
A
]]
{
override
def
op
(
a1
:
List
[
A
],
a2
:
List
[
A
])
:
List
[
A
]
=
a1
++
a2
override
val
zero
:
List
[
A
]
=
Nil
}
val
listMonoidSpec
=
monoidSpec
(
"ListMonoidSpec"
,
listMonoid
[
Int
])
// Exercise 10.1
val
intAddition
=
new
Monoid
[
Int
]
{
override
def
op
(
a1
:
Int
,
a2
:
Int
)
:
Int
=
a1
+
a2
...
...
@@ -41,12 +55,13 @@ object Monoids {
}
// Exercise 10.2
// I'm not sure about the expected semantics..
def
optionMonoid
[
A
]
=
new
Monoid
[
Option
[
A
]]
{
override
def
op
(
a1
:
Option
[
A
],
a2
:
Option
[
A
])
:
Option
[
A
]
=
a1
.
flatMap
(
_
=>
a2
)
override
def
op
(
a1
:
Option
[
A
],
a2
:
Option
[
A
])
:
Option
[
A
]
=
a1
.
orElse
(
a2
)
override
val
zero
:
Option
[
A
]
=
Option
.
empty
}
val
optionMonoidSpec
=
monoidSpec
(
"optionMonoidSpec"
,
optionMonoid
[
Int
])
// Exercise 10.3
def
coendoMonoid
[
A
]
=
new
Monoid
[
A
=>
A
]
{
// hmm, no idea which one should be called first..
...
...
@@ -75,10 +90,22 @@ object Monoids {
foldMap
(
as
,
coendoMonoid
[
B
])(
a
=>
z
=>
f
(
z
,
a
))(
z
)
}
val
foldLeftCorrectness
=
new
Properties
(
"foldLeftCorrectness"
)
{
property
(
"againstListImplementation"
)
=
forAll
{
(
as
:
List
[
Double
])
=>
as
.
foldLeft
(
132.0
)(
_
/
_
)
==
foldLeft
(
as
)(
132.0
)(
_
/
_
)
}
}
def
foldRight
[
A
,
B
](
as
:
List
[
A
])(
z
:
B
)(
f
:
(
A
,
B
)
=>
B
)
:
B
=
{
foldMap
(
as
,
contraendoMonoid
[
B
])(
a
=>
z
=>
f
(
a
,
z
))(
z
)
}
val
foldRightCorrectness
=
new
Properties
(
"foldRightCorrectness"
)
{
property
(
"againstListImplementation"
)
=
forAll
{
(
as
:
List
[
Double
])
=>
as
.
foldRight
(
132.0
)(
_
/
_
)
==
foldRight
(
as
)(
132.0
)(
_
/
_
)
}
}
// Exercise 10.7
def
foldMapV
[
A
,
B
](
v
:
IndexedSeq
[
A
],
m
:
Monoid
[
B
])(
f
:
A
=>
B
)
:
B
=
if
(
v
.
isEmpty
)
m
.
zero
...
...
@@ -251,8 +278,19 @@ object MonoidsPlayground {
// println(ordered(Vector(10, 20, 30, 30, 40)))
// println(ordered(Vector(10, 20, 31, 30, 40)))
optionMonoidSpec
.
check
()
foldLeftCorrectness
.
check
()
foldRightCorrectness
.
check
()
println
(
countWords
(
"the quick brown fox"
,
6
))
println
(
countWords
(
"the quick brown fox"
,
2
))
println
(
countWords
(
"the quick brown fox"
,
100
))
println
(
foldLeft
(
List
[
Double
](
10
,
20
,
3
))(
1.0
)(
_
/
_
))
println
(
List
[
Double
](
10
,
20
,
3
).
foldLeft
(
1.0
)(
_
/
_
))
println
(
foldRight
(
List
[
Double
](
10
,
20
,
3
))(
1.0
)(
_
/
_
))
println
(
List
[
Double
](
10
,
20
,
3
).
foldRight
(
1.0
)(
_
/
_
))
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment