Actually, looking at the type of `processGuess`, guessing correctly does not appear to cost a guess!

processGuess : (letter : Char) ->
               WordState (S guesses) (S letters) ->
               Either (WordState guesses    (S letters))
                      (WordState (S guesses) letters)
Ch 9's definition of `Finished` consist of:

data Finished : Type where
  Lost : (game : WordState 0 (S letters))  -> Finished
  Won  : (game : WordState (S guesses) 0 ) -> Finished


It seems to me that a `Won` case would involve both 0 words and guesses left.

Perhaps this case doesn't apply to the implementation of Hangman in this excellent text?
Thanks. Using v 0.10.2 worked for me:

Idris> the Nat (cast "5")
5 : Nat


However, isn't there a risk of a run-time exception when trying to cast from String -> Nat?

Idris> the Nat (cast "foo")
if with block in Prelude.Interfaces.Prelude.Interfaces.Integer implementation of Prelude.Interfaces.Ord, method > (if intToBool (prim__eqBigInt 0
                           0)
then EQ
else if intToBool (prim__sltBigInt 0
                                   0)
       then LT
       else GT)
0
0
  then S (fromIntegerNat (prim__subBigInt 0 1))
  else 0 : Nat


In short, I'm concerned about an un-safe cast causing a run-time error.
Ch 5 introduces:

readNumber : IO (Maybe Nat)
readNumber = do
    input <- getLine
    if all isDigit (unpack input)
    then pure (Just (cast input))
    else pure Nothing


However, it does not compile on v.0.9.19.1.

*IllegalCode> :r
Type checking ./IllegalCode.idr
IllegalCode.idr:2:12:
When checking right hand side of readNumber:
Can't cast from String to Nat
Holes: Main.readNumber


How can this be fixed?

Thanks
Ch 1, exercise 2 says to implement a function that satisfies:

Vect n elem -> Vect (n * 2) elem


The answer, according to a SO answer, appears somewhat complex (for a first chapter's exercise - I'm supposing).

Please let me know whether the SO answer is the way to go to solve this problem.

Thanks,
Kevin
The Listing 5.5 code sample includes:

import AccountRepository._
val account = checkingAccount("a-123", "John K.", today.some,
            None, Balance(0)).toOption.get #A
val dsl = for {
  b <- updateBalance(account, 10000) #B
  c <- store(b)
  d <- balance(c.no)
} yield d


Would it be worthwhile to include that `Option#get` is a method that should never be used (since it's Partial), but OK to use in a test?
Looking at Listing 4.3, I ran the following in REPL on Scala 2.11.6:

scala> import java.util.Date
import java.util.Date

scala> sealed trait TransactionType
defined trait TransactionType

scala> case object DR extends TransactionType
defined object DR

scala> case object CR extends TransactionType
defined object CR

scala> sealed trait Currency
defined trait Currency

scala> case object USD extends Currency
defined object USD

scala> case object JPY extends Currency
defined object JPY

scala> case object AUD extends Currency
defined object AUD

scala> case object INR extends Currency
defined object INR

scala> case class Money(m: Map[Currency, BigDecimal]) {
     | }
defined class Money

scala> case class Transaction(txid: String, accountNo: String, date: Date,
     | amount: Money, txnType: TransactionType, status: Boolean)
defined class Transaction


However, I'm a bit confused at the following trait's type parameters.

scala> trait Analytics[Transaction, Balance, Money] {
     |   def maxDebitOnDay(txns: List[Transaction]): Money
     |   def sumBalances(bs: List[Balance]): Money
     | }
defined trait Analytics


I can define the following silly Analytics instance:

scala> new Analytics[Int, Int, Int] {
     |   override def maxDebitOnDay(txns: List[Int]) = 100
     |   override def sumBalances(bs: List[Int]) = 100
     | }
res1: Analytics[Int,Int,Int] = $anon$1@7c2dfa2

scala> res1.maxDebitOnDay(List(1,2,3))
res2: Int = 100


These type parameters don't appear to be meaningful, i.e. strongly typed, given that example that I provided.

Perhaps I'm missing something? Should they be sub-type constraints or typeclasses (I look forward to your discussion of them)?
MEAP version 6's page 96 shows:

sealed trait DayOfWeek { 
  val value: Int
  override def toString = value match {
    case 1 => "Monday"
    case 2 => "Tuesday"
    case 3 => "Wednesday"
    case 4 => "Thursday"
    case 5 => "Friday"
    case 6 => "Saturday"
    case 7 => "Sunday"
  }
}

object DayOfWeek { #B
  private def unsafeDayOfWeek(d: Int) = new DayOfWeek { val value = d }
  private val isValid: Int => Boolean = { i => i >= 1 && i <= 7 }
  def dayOfWeek(d: Int): Option[DayOfWeek] = if (isValid(d))
    Some(unsafeDayOfWeek(d)) else None #C
}


I'm curious why an unsafe method, i.e. due to the inexhaustive pattern match, shows up in DayOfWeek#toString.

In the previous chapter, you clearly explained the values of using Algebraic Data Types. This partial function, toString, does not enjoy the benefits of an ADT.

P.S.

By the way, your explanation of lenses was very clear! I had watched videos previously that explained Lenses, but I did not understand them entirely until reading your book.
My mistake, I spoke too soon.

Ch 3 explains sealed traits.

I'll make sure to read the whole book before making comments of this type.
Chapter 2 notes:

Another big advantage with pattern matching in Scala is that the compiler checks for the
exhaustiveness of the pattern match. If you forgot to insert any of the enumerations of
Balance in the pattern match clause, the compiler will issue a warning.


Perhaps it's implied (or expected to an intermediate Scala user), but I think it'd be helpful to note that the sealed keyword is responsible for exhaustiveness.

scala> trait Parent  // not exhaustive
defined trait Parent

scala> case object Boy extends Parent
defined object Boy

scala> case object Girl extends Parent
defined object Girl

scala> def f(p: Parent): Boolean = p match {
     |   case Boy => true
     | }
f: (p: Parent)Boolean
First off, thanks for writing another Scala book. I learned a lot from DSLs in Action - applying your teachings to building a DSL on my last job.

Chapter 2 mentions:

Encoding this type of implementation using OO and
subtyping will lead us to the path of the Visitor pattern [5], which, as we all know is fraught
with grave perils


As a reader with some Java/.NET experience, but working with Scala the past 1.5 years, I'm not aware of the "grave perils" of the Visitor Pattern.

I believe that it'd please be helpful to present a link or brief mention of the problems of the Visitor Pattern.
When I read text books, I like to type out the code and run it.

After going through chapters 1 to 3, I've found it easy to follow along. Thanks for this.

On a second note, I got a bit stuck on ch 4 since I couldn't figure out how to start the node server. I'd appreciate any help.

Thanks,
Kevin

Message was edited by:
kmeredith
I'd like to echo this point.

So far I've found this book to be informative about AngularJS.

However, I've found the exclamations and "wow's that awesome" to detract from the content.

I understand that the authors are passionate about AngularJS, but the words don't need to use needless celebrations.

Multiple Manning books (DSLs in Action, Functional Programming in Scala, SBT in Depth, to name a few) demonstrate the power of their respective topics without resorting to colorful, flamboyant language.

Thanks for this book. I just saw this comment and wanted to echo it.
I agree with the Hello Angular project on ch 1, as well as the comment about the Angello project on ch 2.

It's not obvious what set up (include AngularJS source) is required in order for html to just work.
Page 255/346 (PDF) shows the definition of the `Traverse` trait:

trait Traverse[F[_]] {
def traverse[G[_]:Applicative,A,B](fa: F[A])(f: A => G[B]): G[F[B]] =
sequence(map(fa)(f))
def sequence[G[_]:Applicative,A](fma: F[G[A]]): G[F[A]] =
traverse(fma)(ma => ma)
}

Why are they implemented in terms of each other? After implementing Traverse, I mistakenly executed the traverse method, only to see a Stakoverflow. Note that, of course, the mistake was mine in calling a function (traverse) that calls another function (sequence), which then calls itself endlessly.

Why is a definition, rather than simply a function declaration, provided for these functions?

Thanks for the great book,
Kevin
My understanding of combining Options (via the OptionMonoid) is to apply an implicit Monoid to a type A.

Here's my attempt.

// EXERCISE 2: Give a Monoid instance for combining Options:
def optionMonoid[A](implicit m: Monoid[A]) = new Monoid[Option[A]] {
def op(a1: Option[A], a2: Option[A]) = (a1, a2) match {
case (Some(x), Some(y)) => Some(m.op(x, y))
case (Some(x), _) => Some(m.op(x, m.zero))
case (_, Some(y)) => Some(m.op(m.zero, y))
case _ => Some(m.zero)
}
val zero = None
}

However, for the following test:

val opts: List[Option[Int]] = List(Some(1), Some(2), None, Some(5))
val resOpts = opts.foldLeft(optionMonoid.zero)(optionMonoid.op)
println(resOpts)
assert(resOpts == Some(smilie)

I'm getting a compile-time error.

C:UsersKevinWorkspaceside-workMonoid>scalac MonoidTesting.scala
MonoidTesting.scala:50: error: type mismatch;
found : Option[Int]
required: None.type
val resOpts = opts.foldLeft(optionMonoid.zero)(optionMonoid.op)
^
one error found

Note that I'm using this implicit:

object MonoidTesting {
implicit val m: Monoid[Int] = intAddition

...

val intAddition = new Monoid[Int] {
def op(a1: Int, a2: Int) = a1 + a2
val zero = 0
}

Please advise me on how to understand the OptionMonoid.

Message was edited by:
kmeredith
After typing in the book's code, I got a compilation error that `State` wasn't found.

https://github.com/kman007us/side-work/blob/master/CandyMachine/CandyMachine.scala

How can I define State?

Thanks.
Do I simply need to type

>type State[S, +A] = S => (A,S)

to define "State?"

I did that, but I'm getting a compile-time error, "error: not found: value State"
Thank you, Jacek.
> sealed trait Tree[+A]
> case class Leaf[A](value: A) extends Tree[A]
> case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]

How can I create a new Branch object? Also, what does the "+A" in the Tree mean?

Also, does a Branch's two arguments correspond to 2 Leaf's?

Example: val branch = Branch(Leaf("right"), Leaf("right")) ?

Also, could you please give me a hint as to how to correct my `size` implementation?

object Tree2 extends App {

sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]

def size[A](tree: Branch[A]) : Int = {
def go(x: Branch[A], acc: Int) : Int = (x.left, x.right) match {
case (a: Branch[A], b: Branch[A]) => go(a, acc + 1) + go(b, acc + 1)
case (a: Branch[A], _) => go(a, acc + 1)
case (_, b: Branch[A]) => go(b, acc + 1)
case (_, _) => acc
}
go(tree, 0)
}
}

Message was edited by:
kmeredith
For this Chapter 3 exercise (not listed as an exercise though), the following pattern match is given:

scala> val x = List(1,2,3,4,5) match {
| case Cons(x, Cons(2, Cons(4, _))) => x
| case Nil => 42
| case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
| case Cons(h, t) => h + 1
| case _ => 101
| }

Could you please help me out with the below compile-time errors?

<console>:12: error: constructor cannot be instantiated to expected type;
found : Cons[A]
required: List[Int]
case Cons(x, Cons(2, Cons(4, _))) => x
^
<console>:12: error: recursive value x needs type
case Cons(x, Cons(2, Cons(4, _))) => x
^
<console>:13: error: pattern type is incompatible with expected type;
found : object Nil
required: List[Int]
case Nil => 42
^
<console>:14: error: constructor cannot be instantiated to expected type;
found : Cons[A]
required: List[Int]
case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
^
<console>:15: error: constructor cannot be instantiated to expected type;
found : Cons[A]
required: List[Int]
case Cons(h, t) => h + 1
^
<console>:15: error: not found: value h
case Cons(h, t) => h + 1
^
>def partial1[A,B,C](a: A, f: (A,B) => C): B => C

>EXERCISE 3 (hard): Implement partial1 and write down a concrete usage
>of it. There is only one possible implementation that compiles

Could someone please help me out with this one?

I'm unsure how to start this problem.

Thanks.
The nTimes example makes sense to me - thank you.

However, I don't understand how to fill in the "???" below.

def partial1[A,B,C](a: A, f: (A,B) => C): B => C =
(b: B) => ???

I was thinking (c: C), but I'm not sure which expression to use to produce a C.