М
хотя тут наверное непонятно у меня
М
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
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 описывается последовательность действий, если что
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 это монада