М
хотя тут наверное непонятно у меня
М
uniteBytecode :: [ASMLine] -> String uniteBytecode asm = foldl (++) "" [ bytecode x | x <- asm ]
Anonymous
* encounters line break after let * throw `ParseError`s
М
data ASMLine = ASMLine -- String String { instr :: String , operand :: String , bytecode :: String , offset :: Int } deriving (Eq)
М
ну мне удобнее line break after let
М
строчки экономлю
М
оно 100% законно
Anonymous
Да так даже читаемее, на самом деле. > bytecode :: String Я вот не помню. Любая ли байтовая последователность ли представима в виде Char? foldl (++) "" можно смело заменить на concat или mconcat. Экономишь туалетную^W бумагу для принтера?
М
ага, спс
Artyom
> Любая ли байтовая последователность ли представима в виде Char? да, но зачем
Anonymous
Во, ещё лучше! uniteBytecode = (bytecode =<<)
М
код считает оффсеты строчки от начала
М
а получаются оффсеты от конца
Anonymous
foldl (+) 0 заменимо на sum
М
и чтобы получить - таки оффсеты от начала, я хочу взять длину всего байткода минус оффсет от конца
М
t - length (bytecode x)
Anonymous
type String = [Char] bytecode :: ASMLine -> String => bytecode :: ASMLine -> [Char] concatMap :: (a -> [b]) -> [a] -> [b] (flipped concatMap) assume a ~ ASMLIne, b ~ Char => concatMap bytecode :: ASMLine -> [Char] => concatMap bytecode :: ASMLine -> String
Anonymous
В общем, uniteBytecode = concatMap bytecode, что выражает
Anonymous
@termslang чтобы не считать два раза, можно протащить параметр-аккумулятор длины
Anonymous
И попытайся выразить через foldl или foldr
Anonymous
Всю computeOffsets, я имею ввиду. Кстати, зачем compute? Почему просто не offsets?
Anonymous
Мы ж не в жаве
М
потому что оно будет меняться тыщу раз
Anonymous
Что будет меняться-то? У нас тут иммутабельность и функциональная чистота, вроде как
Anonymous
Достаточно просто написать в документации, что оно O(n^2), например
М
у меня все норм с иммутабельностью
М
вот main
М
module Main where import System.Environment import Emasm main :: IO () main = getArgs >>= return . head >>= readFile >>= return . parseAsmFileContents >>= return . unfoldPseudoasm -- >>= return . splitInitSection >>= return . computeBytecode -- >>= return . uniteBytecode -- >>= return . addLoader -- >>= print >>= mapM_ print
Anonymous
Технически, можно сделать zip... господи
М
offsets больше звучит как переменная
Anonymous
У нас тут своя атмсфера и переменные живут в модулях Data.IORef и Control.Concurrent. Ты из принципов не используешь do-syntax?
М
говорят это плохо
Dmitry
Кто?
М
https://wiki.haskell.org/Do_notation_considered_harmful
Anonymous
Исходную задачу можно сделать, как zip asmLines (scanl _offset [] (map bytecode asmLines)), и останется реализовать только _offset.
Viacheslav
https://wiki.haskell.org/Do_notation_considered_harmful
там не написано, что плохо, написано что иногда плохо
Dmitry
Ньюкомерс майт think
Anonymous
Если поискать, можно и мнение о том, что Monads considered harmful найти. Зачем верить всему подряд?
Dmitry
Ну понятно. Кто автор?
М
ну без монад никак же
М
а без do можно
М
аргументация норм вроде
Dmitry
И без монад можно, какие проблемы
Anonymous
+1, на продолжениях всё делать, как в '92 было
Anonymous
как в Node.js
Viacheslav
Надо на самом деле надо прочитать просто эту статью в вики
Viacheslav
и там примерно во втором абзаце, в топике Didactics написано, что имеется ввиду
Anonymous
А не только её заголовок :)
М
ну где-то кроме монад do лепить точно не надо
Viacheslav
а где-то кроме монад в хаскелле можно?
М
там побочные жффекты описываются
Dmitry
ApplicativeDo ?
Anonymous
Где-то кроме монад заюзать do-нотацию будет затрднительно, потому как оно переписывается в вызовы (>>=) и (>>), ну и (*>), да
Viacheslav
В общем, нормально все с do-нотацией, ее вполне можно использовать, часто она улучшает читаемость кода.
Anonymous
В monadic expression описывается последовательность действий, если что
Viacheslav
ApplicativeDo ?
о, норм, не видел такого
Anonymous
Вброшу https://blog.jle.im/entry/io-monad-considered-harmful.html
Viacheslav
На самом деле клево было бы в целом просто отвязать do-нотацию от монад, аппликативов и привязать просто к оператору >>=
Anonymous
{-# language RebindableSyntax #-}?
Anonymous
https://ocharles.org.uk/blog/guest-posts/2014-12-06-rebindable-syntax.html @termina1
Viacheslav
ну такое
Anonymous
Оно делает именно то, что ты хотел
Viacheslav
нет
Viacheslav
я говорил, что если ты на типе определил просто >>=, то автоматом юзаешь do-syntax, так это тоже можно делать, но это не очень понятно имхо потом
Viacheslav
еще и семантику меняешь
Alexander
нельзя определить просто >>=
Alexander
этим хаскель и хорош, кстати
Viacheslav
Правда?
Anonymous
Другого не завели. Кстати, никогда не пытайтесть выполнить throw $ fix SomeException. По Ctrl-C ghci не прибивается
Viacheslav
Почему это хорошо?
Alexander
потому что такие вещи пакуются в неймспейсы
Anonymous
Можно определить >>=, в локальном контексте. Но do-нотация всё равно рассахаривается в Prelude.>>=
Alexander
в целом можно рассахаривать и в >>=
Alexander
через RebindableSyntax
Alexander
Например, если не любишь прелюдию
Anonymous
Мы его только что поминали)
Alexander
вот да
Alexander
суть в другом, что если у тебя есть >>= то ты описываешь контракт на этот метод через тайпкласс
Alexander
собственно, внезапно, все что имеет >>= и return это монада