- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
{- This code intentionally was made slightly cryptic -}
{-# LANGUAGE GADTs, StandaloneDeriving, UnicodeSyntax, KindSignatures, FlexibleInstances, LambdaCase, CPP, BangPatterns #-}
import System.Exit
import Data.Functor
import Control.Monad.IO.Class
import Control.Monad.Trans.Cont
import System.Random
import System.Posix.Signals
import System.Environment
import Control.Concurrent.MVar
instance Eq (Int → Int) where
_ == _ = True -- It's a hack
infixl 7 :.
data T ∷ * where {J, Â, Â', S, K ∷ T; (:.) ∷ T → T → T; Ψ ∷ {σ ∷ String} → T
;F ∷ (Int → Int) → T; N ∷ Int → T; Ø ∷ String → T}
parse ∷ String → [T] → T
parse ('f':'u':c) t = parse c (J:t)
parse ('b':'a':'r':c) t = parse c (Â:t)
parse ('~':c) (a:b:t) = parse c (b:.a:t)
parse ('~':_) _ = error "Parse error: missing operand(s)"
parse (_:c) t = parse c t
parse [] (h:_) = h :. Ψ []
parse [] [] = error "Parse error: empty program"
s ∷ T → T
s (J :. x) = (x :. S) :. K
s (K :. x :. _) = x
s (S :. x :. y :. z) = (x :. z) :. (y :. z)
s (F f :. N i) = N $ f i
s (F f :. F g) = F $ f . g
s (Â' :. N i :. ψ @ (Ψ {})) = ψ {σ = toEnum i : σ ψ}
s (Â :. n :. ψ @ (Ψ {})) = Â' :. (n :. F (+1) :. N 0) :. ψ
-- Other cases
s (a :. b) = (s a) :. (s b)
s x = x
eval ∷ (T → t) → (T → t) → T → t
eval fp done t | t == t' = done t
| otherwise = fp t'
where t' = s t
ψs a@Ψ{σ=s} = [(a, s)]
ψs (a:.b) = ψs a ++ ψs b
ψs _ = []
r' ∷ T → [(T, String)] -- Very inefficient; should be rewritten
r' a | null t = [(a, s)] where ((_, s):t) = ψs a
r' (a :. b) = r' a ++ r' b
r' _ = []
r ∷ T → IO (Maybe T)
r t = case r' t of
[] → return Nothing
t' → ((t' !!) <$> randomRIO (0, length t' - 1)) >>= \case
(Ψ{}, s) → putStrLn (reverse s) >> return Nothing
(t'', s) → putStrLn (reverse s) >> return (Just t'')
setMVar v = (tryTakeMVar v >>) . putMVar v
loop v f n = callCC $ \done → loop1 done (\fp → f fp done) n
where loop2 interrupt f' n = do
n' ← liftIO (readMVar v) >>= \case
0 → f' interrupt n
_ → callCC $ \fp → f' fp n
liftIO $ modifyMVar_ v $ (\k → return $ k-1)
loop2 interrupt f' n'
loop1 done f' n = do
n' ← callCC $ \int → loop2 int f' n
liftIO $ putStrLn "Measure (m) Abort (a) Continue (c) Run steps (number)"
(liftIO getLine) >>= \case
"a" → f' done n' >> return ()
"c" → liftIO $ setMVar v (-1)
"m" → liftIO (r n') >>= \case
Nothing → liftIO exitSuccess
Just n'' → loop1 done f' n'' >> return ()
a → case readsPrec 0 a of
(n,_):_ → liftIO $ setMVar v n
_ → liftIO $ putStrLn "Not understood."
loop1 done f' n'
main ∷ IO ()
main = do
(file, n) ← getArgs >>= \case
[f] → return (f, -1)
["-s", n, f] → case readsPrec 0 n of
(n',_):_ → return (f, n')
_ → error "Argument of -s should be a number"
_ → error "Insufficient arguments. Expected [-s NUMBER_OF_STEPS] FILE"
cnt ← newMVar n
installHandler keyboardSignal (Catch $ setMVar cnt 0) Nothing
void $ (r =<<) (evalContT $ loop cnt eval =<< (parse <$> readFile file))
CHayT 18.03.2016 00:16 # 0
guest 18.03.2016 03:02 # +6
люблю CLR и люблю функциональщину
но у меня на клавиатуре нету ψ, и потому мне он не подойдет
придется делать стартап на пхп
LispGovno 18.03.2016 08:58 # 0
guest 18.03.2016 10:08 # 0
https://wiki.haskell.org/Haskell_in_industry
если у тебя в продакшене только пхп, это не значит что у других так же
3_14dar 18.03.2016 15:38 # 0
guest 19.03.2016 00:39 # 0
ну вот я привел пример что пишут
что не так-то?
3_14dar 19.03.2016 16:08 # −1
guest 19.03.2016 17:58 # 0
да, в целом функциональные языки как прекрсная дама: все программисты на них дрочат по ночам, а с утра идут писать тупой импетаривный бойлерплейтовый код
guest 19.03.2016 18:07 # 0
guest 19.03.2016 18:10 # −1
так ведь и на скале же пишут порой
bormand 19.03.2016 18:25 # 0
Походу, там проще будет написать процессор, а под него уже компилить стрелялку обычным gcc...
guest 19.03.2016 18:27 # +2
Но лучше взять шланг: все таки llvm лучше позволяет делать бекенды
bormand 19.03.2016 18:28 # +2
malbodge-процессор для защиты от реверса и патчей...
guest 19.03.2016 18:31 # +3
ножки должны называться @, C2 и ##.
Чтобы создатели обвязки епнулись
bormand 19.03.2016 18:35 # +3
З.Ы. Там же троичная логика ещё... Так что ещё и по 3 логических уровня на ногах... Ну и двуполярное питание, как на советских операционниках... Тогда весь стандартный обвес сразу пролетает.
inkanus-gray 20.03.2016 00:48 # +3
inkanus-gray 20.03.2016 00:59 # +1
Отсюда: http://www.trinitas.ru/rus/doc/0226/002a/02260054.htm
Где бы найти эту свалку...
kegdan 20.03.2016 01:05 # +3
inkanus-gray 20.03.2016 01:06 # 0
kegdan 20.03.2016 01:07 # +8
inkanus-gray 20.03.2016 01:14 # +2
kegdan 20.03.2016 01:15 # 0
3_14dar 20.03.2016 01:06 # 0
3.14159265 21.03.2016 17:25 # +2
Врунишка. Каждый раз когда ты лжёшь где-то в мире на пхп обезьянами пишутся очередные даты. Не делай больше так.
3_14dar 21.03.2016 20:37 # 0
Это к васе.
kegdan 20.03.2016 01:06 # +1
inkanus-gray 20.03.2016 01:08 # +2
kegdan 20.03.2016 01:11 # −1
Просто читал об этом. Вот если бы реальный физический трит был - тогда совсем другое дело бы было.
bormand 20.03.2016 08:06 # 0
"Так что ещё и по 3 логических уровня на ногах... Ну и двуполярное питание, как на советских операционниках..."
kegdan 20.03.2016 08:09 # 0
bormand 20.03.2016 08:10 # +1
MLC флеш вон 4 варианта в одной ячейке хранит, а TLC - все 8. Именно уровнями. И ничто не мешает сделать 3 или 9. Так что физическая база есть, было бы желание и профит...
Просто никому нахуй не упёрлась непривычная троичная арифметика.
kegdan 20.03.2016 08:41 # 0
Триты же выгоднее в плане хранения информации.
Хотя если учесть какой пиздец начнется при переносе существующего кода на такие машины и то что некоторые бородатые прогеры до сих пор матерят Билли за ООП в винде...
bormand 20.03.2016 08:47 # 0
Ну вот для хранения как раз юзают. Только не 3, а удобные для остальной схемы 4 и 8 уровней.
А логику и арифметику с тремя уровнями делать - тот ещё пиздец.
bormand 20.03.2016 08:58 # 0
Купи FPGA, замути эмуляцию тритов через 2 бита и вперёд, хуярить троичный проц и портировать на него сишку ;)
kegdan 20.03.2016 08:58 # 0
bormand 20.03.2016 09:12 # 0
kegdan 20.03.2016 09:14 # 0
bormand 20.03.2016 09:24 # +1
Ну ты прям как немец мыслишь, что кроме своей специальности человек никогда ничего не осилит...
Если интересно что-то - бери да изучай, пока мозги не засохли да время есть (с работой будет меньше).
kegdan 20.03.2016 11:10 # 0
inkanus-gray 20.03.2016 14:07 # 0
А ещё можно подобрать троичную «Сетунь» на свалке...
Vasiliy 20.03.2016 16:49 # +2
inkanus-gray 20.03.2016 17:19 # +1
kegdan 20.03.2016 17:44 # 0
http://lurkmore.so/images/thumb/6/67/%D0%98%D0%B3%D0%BE%D1%80%D1%8C_%D1%82%D0%BE%D0%BD%D0%B5%D1%82.png/250px-%D0%98%D0%B3%D0%BE%D1%80%D1%8C_%D1%82%D0%BE%D0%BD%D0%B5%D1%82.png
3_14dar 20.03.2016 23:05 # +4
Vasiliy 21.03.2016 13:29 # −1
3_14dar 21.03.2016 20:36 # +2
3.14159265 21.03.2016 17:28 # +4
ААААААААААААААА!!!!1111111111 Что ж ты делаешь, ирод? Я коллег перепугал хохотом. Думаю это агенты Путина
inkanus-gray 21.03.2016 20:26 # 0
3_14dar 21.03.2016 20:36 # 0
bormand 21.03.2016 20:40 # +3
Дозиметром проверил?
kegdan 21.03.2016 20:56 # −1
bormand 21.03.2016 20:57 # +2
А, так вот зачем у нас колбасу туалетной бумагой соей разбавляют... Заботятся о людях, значит.
kegdan 21.03.2016 20:59 # +1
3.14159265 21.03.2016 17:30 # +1
Их либы даже человеку пересаживают.
bormand 21.03.2016 18:48 # +1
И даже рисовали когда-то...
3.14159265 21.03.2016 19:07 # +3
bormand 21.03.2016 19:11 # 0
3.14159265 21.03.2016 19:26 # 0
wvxvw 19.03.2016 19:01 # 0
bormand 19.03.2016 19:03 # 0
wvxvw 19.03.2016 19:22 # 0
Я почти никогда ту часть проекта не собираю, только по праздникам. Проблем пока не было, но я и внутрь особенно не заглядывал.
3_14dar 19.03.2016 19:19 # 0
Из /pr/ (а других ты и не знаешь)?
guest 01.04.2016 01:51 # −1
нормальные программеры любят хаскель
3_14dar 01.04.2016 01:52 # 0
>/pr/
В самый раз, что не так?
guest 01.04.2016 01:54 # −1
я сказал что хорошие программисты любят хаскель
любит-ли его прыщепублика в /pr/. -- мне не ведомо
это же ты в /pr/ постоянно тусишь
3_14dar 01.04.2016 04:00 # 0
guest 01.04.2016 16:19 # +1
Antervis 18.03.2016 09:15 # +1
"ты либо говно пиши, либо плохо обфусцируй"
guest 29.03.2016 22:33 # 0
Всё новое - это хорошо забытое старое? Interact?
CHayT 29.03.2016 23:37 # +4
короче, такая модель I/O, как в этом языке, ещё вроде нигде не описана (потому что она идиотская)
это практическая проверка гипотезы Снаута, что любое чисто-функциональное I/O строится на скрытии неких данных от кого-то
поскольку в чистая функция всегда возвращает одно и то же для одинаковых входных данных, для описания I/O используют некий дополнительный параметр (зачастую фиктивный) в котором, якобы, хранится состояние всего мира (io в Mercury, RealWorld в Haskell)
т.е. получили на вход реальный мир (q), сделали с ним что-то (распечатали строку на экран), и вернули новый мир (q'), где строка напечатана
взяли новый мир q', где распечатана строка, запустили ракеты и получили мир q'', и т.д.
вроде всё прекрасно и чисто функционально, но ушлый юзер может после этого начать снова пользовать ссылку на мир q, скажем
это означает, что он возвращается во времени к моменту, где строка на экран ещё не напечатана и ракеты не запущены
т.е. чтобы выполнить такой код, рантайм языка должен восстановить пользователя из радиоактивного пепла и потом стереть его память
пока такого ещё не изобрели, и текущее решение состоит в том, чтобы запретить программисту трогать ссылки на старые миры
unique types просто запрещают их трогать: юзать можно, но ровно один раз, а потом низзя!!
монадки делают то же самое, но хитрее: ссылка на RealWorld просто не экспортируется из модуля, так что работать с ней может только узкий круг доверенных функций из этого модуля, которые уж точно назад во времени не путешествуют
т.е. и в том и в другом случае есть скрытие каких-то данных
CHayT 29.03.2016 23:37 # +2
в результате, программист может наплодить сколько угодно миров
стирать память мы по-прежнему не умеем, поэтому нужно снова применить скрытие
только скрывать мы будем не данные от программиста, а результат работы программы от пользователя
т.е. если запустить программу на этом языке, не произойдёт ничего, она просто повиснет
однако побочные эффекты программы можно "измерить"
например, заинтерраптив её
при "измерении" из всего множества миров остаётся один из них, и только тогда можно понять, какой именно
к примеру, есть такой псевдокод:
main(q)=
let
q' = print(q, "пидар идёт ")
f(a,b) = a -- без разницы, что делает f
in f(print(q', "нахуй"), print(q', "напитон"))
видно, что мы использовали q' дважды и получили в итоге два разных мира
при измерении побочных эффектов этой программы мы с равной верятностью получим вывод "пидар идёт нахуй" и "пидар идёт напитон"
в реальности всё чуть сложнее, поскольку мы манипулируем не просто строками, а термами языка, но это не суть
это касается вывода
ввод тоже есть (при сильном желании)
CHayT 29.03.2016 23:43 # +2
как мы помним, все миры равновероятны
но если скопировать один мир много раз (т.е. начать писать "нахуй" в бесконечном цикле), очевидно же, что чем дольше выполнять программу, тем с большей вероятностью пидар пойдёт нахуй
на этом и строится, собственно, ввод
3_14dar 30.03.2016 00:37 # −2
bormand 30.03.2016 07:25 # +3
kegdan 30.03.2016 08:05 # 0
3_14dar 30.03.2016 17:39 # −4
Vasiliy 30.03.2016 17:40 # −4
3_14dar 30.03.2016 18:09 # −4
Vasiliy 30.03.2016 18:12 # −4
3_14dar 30.03.2016 21:22 # −3
Vasiliy 30.03.2016 21:23 # −3
3_14dar 30.03.2016 21:32 # −3
Vasiliy 30.03.2016 22:31 # −3
3_14dar 30.03.2016 23:41 # 0
Vasiliy 31.03.2016 11:09 # 0
guest 01.04.2016 13:49 # 0
guest 01.04.2016 13:48 # −1