Я сделал некоторое программирование PIC - главным образом, потому что мне понравилась идея, микросхема была только долларом или два. Однако для новичка, принимая решение только на цене преждевременная оптимизация.
Программирование в ассемблере является опытом. В основном необходимо изучить приблизительно 100 понятий, прежде чем можно будет мигнуть светодиодом. (Сторожевой таймер, контакты сброса, 8-разрядные счетчики/переполнение, циклы задержки, шестнадцатеричное число, двоичный файл, побитовое маскирование, прерывания, прерывает запросы на обслуживание, порты IO, и т.д.), Это является все очень образовательным - и большое чувство для получения так близко к машине - но способность кодировать что-то в C скроет часть этой сложности, таким образом, можно будет сфокусироваться на результатах. Поэтому я сказал бы, идут с AVR. (И я полагаю, что цены теперь ближе к PIC)
Также: Если Вы интересуетесь добиванием цели (и не возражайте тратить ~ 30$), проверьте arduino. Парень, продающий им в моем локальном магазине электроники, говорил, что продает тонны их студентам отделения гуманитарных наук. (Это использует IDE из проекта Обработки и компилирует код с avr-gcc.)
Обновление: Фиксированный комментарий, что выполнения Ардуино интерпретировали код. Также обновленный приблизительно цена Ардуино.
scala> abstract class Stack {
| def push(n :Int):Stack
| }
defined class Stack
scala> final case class push(st :Stack,hd :Int) extends Stack {
| override def push(n :Int):Stack = new push(this,n)
| }
defined class push
scala> object NullStack extends Stack {
| override def push(n :Int):Stack = new push(null,n)
| }
defined module NullStack
scala> val s = NullStack.push(1).push(2)
s: Stack = push(push(null,1),2)
scala> def test(s :Stack) = s match { case st push i => println(st +"push " + i) }
test: (Stack)Unit
scala> test(s)
push(null,1)push 2
Фактически, тот факт, что :: является классом case, является только половина ответа. Причина, по которой это работает при сопоставлении с образцом, заключается в том, что существует экстрактор для объекта ::, который генерируется автоматически при определении класса case. Для удобства ::. Unapply возвращает список, потому что :: расширяет список. Однако, если вы хотите использовать тот же прием для списков, вы не сможете расширить List, потому что это final . Что вы можете сделать, так это определить объект с помощью соответствующего метода неприменения, который имеет ожидаемую сигнатуру возврата. Например, чтобы сопоставить последний элемент списка, вы можете сделать:
object ::> {def unapply[A] (l: List[A]) = Some( (l.init, l.last) )}
List(1, 2, 3) match {
case _ ::> last => println(last)
}
(1 to 9).toList match {
case List(1, 2, 3, 4, 5, 6, 7, 8) ::> 9 => "woah!"
}
(1 to 9).toList match {
case List(1, 2, 3, 4, 5, 6, 7) ::> 8 ::> 9 => "w00t!"
}
Экстрактор должен возвращать Option, который содержит кортеж из двух деконструированных элементов.
Подробно на странице 301 документа Программирование на Scala , О сопоставлении с образцом в List
s.
Шаблон «cons»
x :: xs
- частный случай инфикса схема работы. Вы уже знаете, что если рассматривать как выражение, инфиксная операция эквивалентна вызову метода. Для выкройки правила разные: если рассматривать как образец, инфиксная операция, такая какp op q
эквивалентноop (p, q)
. То есть инфиксный операторop
обрабатывается как шаблон конструктора. В частности, шаблон cons, такой какx :: xs
, обрабатывается как: :( x, xs)
. Это намекает на то, что должен быть класс с именем::
, который соответствует шаблону конструктор. Действительно есть такой класс. Он называетсяscala. ::
и является именно тем классом, который строит непустые списки.