2014-11-26 5 views
0

Хорошо, я наконец-то понял смысл использования неявных параметров функции и получил мои классы классов. Давайте посмотрим на мою монады класса типа:Scala неявный параметр

trait Monad[M[_]] extends Functor[M] { self => 
    def pure[a](value: a): M[a] 

    def flatMap[a, b](ma: M[a])(f: a => M[b]): M[b] 
} 

Я создал экземпляр класса типа для моего парсера монады (это просто манекен сейчас):

case class Parser[a](value: (Unit => a)) { 
    def >>=[b](f: a => Parser[b])(implicit p: Monad[Parser]): Parser[b] = 
    p.flatMap(this)(f) 

    def fmap[b](f: a => Parser[b])(implicit p: Monad[Parser]): Parser[b] = 
    p.map(this)(f) 
} 

object Parser { 
    implicit object MonadInstance extends Monad[Parser] { 
    override def pure[a](value: a): Parser[a] = 
     new Parser[a]({ _ => value }) 

    override def flatMap[a, b](ma: Parser[a])(f: (a) => Parser[b]): Parser[b] = 
     f(ma.value()) 

    override def map[a, b](fa: Parser[a])(f: (a) => b): Parser[b] = 
     new Parser[b]({ _ => f(fa.value()) }) 
    } 
} 

Я просто интересно, если я могу использовать экземпляр монады без необходимости объявлять неявный параметр везде, где я использую свои монады. Есть ли способ «импортировать» функциональность по всему миру?

+0

Если у вас есть определенный тип, вы можете вызвать неявное, где вам нужно, 'неявно [Monad [Parser]]'. Но вы не можете и не должны иметь возможность добавлять функции к объекту совершенно незаметно - это будет рецепт невозможного нечитаемого кода и кошмарной отладки. – lmm

ответ

0

Там есть метод Predef называется неявным, который предназначен для этого случая использования:

def implicitly[T](implicit t: T):T = t 

, который может быть использован, как это:

val mParser = implicitly[Monad[Parser]] 

Оригинал:

В Скале, implicits автоматически просматриваются в сопутствующих объектах соответствующих типов. Поэтому неявно [Monad [Parser]] должен просто работать, потому что он должен выглядеть в объекте Parser.

Обратите внимание, что из-за того, как работает интерпретатор, это немного больно для определения сопутствующих объектов в repl. Самое простое - обернуть их в объект или не запустить объект Parser на новой строке (только для repl).

+0

Я действительно хотел знать, есть ли другой способ автоматического получения экземпляра класса типа для монарды синтаксического анализатора. Но в любом случае примечание о REPL приятно знать. – bash0r

+0

Если вы используете: вставьте, то repl будет скомпилировать код как один блок, чтобы вы могли вместе определить объект-компаньон. –

+0

@ bash0r ах, вы имеете в виду, возможно, неявно [Monad [Parser]]? – dlwh

Смежные вопросы