SMT-солверы
Есть ли scala-библиотека для решения SMT, опубликованная в каком-нибудь репозитарии, доступном из sbt? Я ни одной не нашел, все, что есть - только самому собирать.
By logging in to LiveJournal using a third-party service you accept LiveJournal's User agreement
select * from jr where (id1, id2) in ( ('000002e4-6b99-45ac-9187-4d00b7b457fc', 'a1c4fa6f-370c-11e6-bb37-f832e4bd9ad8'), ('00011eaf-f65d-42a7-ae54-3b16dff65f22','4834f6b6-af4a-4cc5-88d6-924a84f0ef31'));
def createTransform(e: Event): State => State = ... val transform = events foldMap createTransform transform(state)Логично ?
def commonSuffix(s1: String, s2: String): String = { val n = (s1.reverseIterator zip s2.reverseIterator) .takeWhile {case (a, b) => a == b} .size s1.substring(s1.length - n) // is substring efficient ? }А как найти общее окончание для нескольких строк ?
case class NewPost(...) type NewPostSubscriber = NewPost => Either[Exception, Unit]Допустим, что все эти функции не зависят друг от друга и либо не возвращают ничего в случае удачного завершения, либо возвращают ошибку. Предположим также, что все возвращаемые ошибки нужно аккумулировать.
// invoke all subscribers with a NewPost event def fireNewPost(event: NewPost, subscribers: List[NewPostSubscriber]) = { val invokeAll = subscribers foldMap { s => s map (_.toValidatedNel) } map (_.toEither) invokeAll(event) }Как вам такое решение ?
def pair(a: Array[Int], target: Int): Option[(Int, Int)] = { var left = 0 var right = a.length - 1 var result: Option[(Int, Int)] = None while (left < right && result.isEmpty) { (a(left), a(right)) match { case (x, y) if x + y == target => result = Some(x, y) case (x, y) if x + y < target => left = left + 1 case (x, y) if x + y > target => right = right - 1 } } result }А что если нам нужно найти не одну а все пары элементов массива, сумма которых равна target'у ?
def pairs(a: Array[Int], target: Int): List[(Int, Int)] = { var left = 0 var right = a.length - 1 var result: List[(Int, Int)] = List() while (left < right) { (a(left), a(right)) match { case (x, y) if x + y == target => result = result :+ (x, y); left = left + 1 case (x, y) if x + y < target => left = left + 1 case (x, y) if x + y > target => right = right - 1 } } result }А можно обойтись без copy-paste ?
def streamOfPairs(a: Array[Int], target: Int): Stream[(Int, Int)] = Stream.iterate(a) { xs => if (xs.head + xs.last > target) xs.init else xs.tail } .take(a.length - 1) .map { xs => (xs.head, xs.last) }А теперь из полученного "стрима" легко получим как одну, так и все искомые пары:
def pair(a: Array[Int], target: Int): Option[(Int, Int)] = streamOfPairs(a, target) find { case (x, y) => x + y == target } def pairs(a: Array[Int], target: Int): List[(Int, Int)] = (streamOfPairs(a, target) filter { case (x, y) => x + y == target }).toListКак видим, "функциональный подход" помог нам избавиться от copy-paste и упростить решение.
type Content = String def readFile(fileName: String): Try[Content] = ???Нам нужно написать функцию readFile(fileNames: List[String]), которая бы читала все файлы по очереди и возвращала содержимое первого успешно считанного файла. Тогда эта функция будет выглядеть так:
def readFile(fileNames: List[String]): Either[Content, List[Throwable]]А что, если нам нужно вместе с содержимым получить список ошибок, которые случились до того ? Тогда функция будет:
def readFile(fileNames: List[String]): Either[(Content, List[Throwable]), List[Throwable]]Как написать такую функцию ?
def readFiles(fileNames: List[String]): Either[List[Throwable], List[String]] = ???Предположим у нас есть уже функция для чтения одного файла:
def readFile(fileName: String): Try[String] = ???Как написать функцию readFiles без использования моноидов как в предыдущем посте ?