Я решил попробовать посмотреть, понимаю ли я как работает ленивость в ghci, в итоге у меня получилась следующая сессия:
Prelude> let x = (id True, id undefined)
Prelude> :sprint x
x = _
Prelude> let x = (True, id undefined)
Prelude> :sprint x
x = _
Prelude> let x = (True, undefined)
Prelude> :sprint x
x = (,) True _
Prelude> let x = (True, undefined::Int)
Prelude> :sprint x
x = (True,_)
Prelude> let x = (True, False)
Prelude> :sprint x
x = (True,False)
но я абсолютно не понимаю, почему я получаю такие результаты.. Может ли кто-нибудь помочь разобраться?
У меня возникла достаточно странная задача. Мне нужно оборачивать, некоторые объекты (возможно заранее неизвестного типа), в прокси, которое будет передавать их дальше настоящему объекту специальным образом. Если нужен пример, то для простоты, допустим будет логировать то, что имя вызываемой функции и параметры (но на самом деле там логика более сложная). Т.е. в идеале хочется, что-то вроде.
Чтобы исключить X-Y проблему.
На самом деле задача открывать соединение в одном процессе, а делать запросы в другом отфоркнутом от первого (эта часть задачи не обсуждается). Соответственно идеей решения было создать такой прокси объект, в который будет передавать запрос в родительский процесс, там он будет выполняться и получать результат назад.
Соответственно вопрос, есть ли тут более адекватные решения данной задачи, чем предложенное и есть ли адекватные способы только на уровне R реализации идеи решения.
Есть простенький код (Олеговские регионы, если кто не узнал), в нём хочется убрать перекрывающиеся инстансы для RMonad, что в принципе возможно при использовании закрытых семейств типов, например как описано ниже. Это почти работает, почти, т.к. в одном из тестов типы перестают выводиться (ошибка снизу поста). Вопрос, что с этим делать, ну не считая того, что доуменьшить пример, в очередной раз проконсультироваться с Олегом и послать баг репорт?
{-# LANGUAGE Rank2Types, GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DataKinds, KindSignatures, MultiParamTypeClasses, TypeFamilies, FlexibleInstances, UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables, FlexibleContexts #-}
import System.IO
import Control.Applicative
import Control.Monad.Reader
import Control.Monad.Trans
import Control.Exception
import Data.IORef
newtype IORT s m v = IORT{ unIORT:: ReaderT (IORef [HandleR]) m v }
deriving (Functor, Applicative, Monad)
newtype SHandle (m :: * -> *) = SHandle Handle -- data ctor not exported
newtype HandleR = HandleR Handle
class (Monad m1, Monad m2) => MonadRaise m1 m2 where
lifts :: m1 a -> m2 a
type family TEQ (a :: * -> *) (b :: * -> *) :: Bool where
TEQ m m = True
TEQ m1 (IORT s m2) = False
data Proxy (b::Bool) = Proxy
class (Monad m1, Monad m2) => MonadRaise' (b::Bool) m1 m2 where
lifts' :: Proxy b -> m1 a -> m2 a
instance (MonadRaise' (TEQ m1 m2) m1 m2) => MonadRaise m1 m2 where
lifts = lifts' (Proxy::Proxy (TEQ m1 m2))
instance (Monad m1, Monad m2, m1 ~ m2) => MonadRaise' True m1 m2 where
lifts' _ = id
instance (Monad m2, m2 ~ (IORT s m2'), MonadRaise m1 m2')
=> MonadRaise' False m1 m2 where
lifts' _ = IORT . lift . lifts
test_copy fname_in fname_out = do
hout <- newSHandle fname_out WriteMode
(do newRgn (do
till (return True)
(return "foo" >>= shPutStrLn hout)))
newSHandle :: (m ~ (IORT s' m'), SMonad1IO m) =>
FilePath -> IOMode -> m (SHandle m)
newSHandle = undefined
newRgn :: RMonadIO m => (forall s. IORT s m v) -> m v
newRgn = undefined
till :: forall (m :: * -> *) a. Monad m => m Bool -> m a -> m ()
till condition iteration = loop where
loop = do b <- condition
if b then return () else iteration >> loop
shPutStrLn :: (MonadRaise m1 m2, SMonadIO m2) => SHandle m1 -> String -> m2 ()
shPutStrLn = undefined
-- RMonad:
class Monad m => RMonadIO m where lIO :: IO a -> m a
instance RMonadIO IO where lIO = id
instance RMonadIO m => RMonadIO (ReaderT r m) where lIO = lift . lIO
instance RMonadIO m => RMonadIO (IORT s m) where lIO = IORT . lIO
-- SMonadIO
class RMonadIO m => SMonadIO m
instance RMonadIO m => SMonadIO (IORT s m)
-- SMonad1IO
class RMonadIO (UnIORT m) => SMonad1IO m
instance RMonadIO m => SMonad1IO (IORT s m)
type family UnIORT (m :: * -> *) :: * -> *
type instance UnIORT (IORT s m) = m
Ошибка:
Minimal.hs:45:32:
Could not deduce (MonadRaise'
(TEQ (IORT s' m') (IORT s (IORT s' m')))
(IORT s' m')
(IORT s (IORT s' m')))
arising from a use of ‘shPutStrLn’
from the context (RMonadIO m')
bound by the inferred type of
test_copy :: RMonadIO m' => t -> FilePath -> IORT s' m' ()
at Minimal.hs:(41,1)-(45,49)
In the second argument of ‘(>>=)’, namely ‘shPutStrLn hout’
In the second argument of ‘till’, namely
‘(return "foo" >>= shPutStrLn hout)’
In a stmt of a 'do' block:
till (return True) (return "foo" >>= shPutStrLn hout)
> {-# LANGUAGE DataKinds, TypeOperators, KindSignatures, GADTs, ConstraintKinds, TypeFamilies, UndecidableInstances #-}
>
> import GHC.TypeLits
> import Data.Constraint
> import Data.Proxy
> data Proof2 :: (Nat -> Constraint) -> * where
> Proof2 :: c n => Proxy n -> Proof2 c
>
> type family LessThen255 n :: Constraint where
> LessThen255 f = (f <= 255)
>
> one :: LessThen255 n => Proxy n -> Proof2 LessThen255
> one = Proof2
Выдает очень неожиданное
Min.lhs:14:9:
Could not deduce (LessThen255 n) arising from a use of ‘Proof2’
from the context (LessThen255 n)
bound by the type signature for
one :: (LessThen255 n) => Proxy n -> Proof2 LessThen255
куда копать?
P.S. изменение на
> data Proof2 :: (Nat -> Constraint) -> Nat -> * where
> Proof2 :: c n => Proxy n -> Proof2 c n
Правильно ли я понимаю, что функция getAnyProcessStatus данная функция будучи запущенной без WNOHANG (True третьим параметром) создаст (использует ранее созданный) дополнительный OS тред и будет в нём висеть?
Подскажите пожалуйста, что не так в коде ниже и почему генерируется кривой, на мой взгляд бинарный код.
Ниже приведена программа демонстрирующая неправильное и правильное поведение
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
module Main where
import Foreign
import Unsafe.Coerce
-- определение домена значений
data M = A | B deriving (Show, Eq)
-- типизированный доменом значений wrapper
-- в реальной программе враппер вокруг указателя
newtype S (a :: M) = S Int
-- экзестенциальный тип, позволяющий показывать, что
-- реальный тип S не известен на момент компиляции
data SomeS = forall a . SomeS (S a)
-- View тип для S, позволяет просматривать структуру
-- внешнего объекта
data V0 :: M -> * where
V0A :: Int -> V0 A
V0B :: Double -> V0 B
-- Другой вариант V, с полиморфным конструктором
-- нужен для демонстрации
data V1 :: M -> * where
V1A :: Int -> V1 A
V1B :: Double -> V1 B
V1a :: () -> V1 a
-- создание View
viewV0 :: S a -> V0 a
viewV0 (S i)
| even i = unsafeCoerce $ V0A 1
| otherwise = unsafeCoerce $ V0B 2
-- создание View
viewV1 :: S a -> V1 a
viewV1 (S i)
| even i = unsafeCoerce $ V1A 1
| otherwise = unsafeCoerce $ V1B 2
-- определение типа S
typeOf :: S a -> M
typeOf (S i) = if even i then A else B
-- Приведение SomeS к определенному типу.
-- тут в общем-то вся проблема т.к. тип неверный и если
-- его подправить, то все хорошо, но мне интересно
-- поведение при полиморфном результате cast
cast :: M -> SomeS -> S a
cast ty (SomeS s@(S i))
| ty == typeOf s = S i
| otherwise = error "cast"
-- Тесты
test0 :: IO ()
test0 =
let s = cast A (SomeS (S 0))
in case viewV0 s of
V0A{} -> putStrLn "test0 - A"
V0B{} -> putStrLn "test0 - B"
test1 :: IO ()
test1 =
let s = cast A (SomeS (S 2)) :: S A
in case viewV0 s of
V0A{} -> putStrLn "test1 - A"
test2 :: IO ()
test2 =
let s = cast A (SomeS (S 4))
in case viewV1 s of
V1A{} -> putStrLn "test2 - A"
V1B{} -> putStrLn "test2 - B"
V1a{} -> putStrLn "test2 - O_o"
main = do
test0 -- no ouput at all
test1 -- A
test2 -- O_o
В то время как ожидается, что все тесты выведут 'A', даже если не так то полное отсутвие действия в первом тесте мягко говоря удивляет.
Kazu Yamamoto в очередной раз улучшил свой веб сервер mightyhttpd, и в очередной раз обогнал nginx в полтора раза. Хотелось бы повторить такой тест, посему хочется спросить, как можно тонко настроить nginx чтобы он позорно не слил? Тестировать собираюсь минимум на одном своём ноуте.
Пост в девелопмент, т.к. он больше про написание эффективных веб серверов, а не администрирование.
Интересуют вопросы:
Как правильно настраивать nginx, mighty и систему для быстрой отдачи пары стат страниц.
После долгой задержки (практически 11 месяцев) вышла очередная версия системы управления сервисами OpenRC. OpenRC — основанная на init система управления сервисами, поддерживающая зависимости. Данная система используется в различных дистрибутивах Linux и BSD.
В данный момент ведутся работы по поддержке других init-систем и использовании их возможностей в openrc.
Важной новостью является выделение модулей сети в отдельное приложение netifrc, поэтому те пользователи, которые не используют его, могут отключить эти модули. Также ведутся работы по адаптации netifrc под другие системы управления сервисами.
Прекрасное введение в линзы, отличная статья, с подробными примерами и интересным оформлением, в отличии от скучных статей про монады. Заодно показывает суть хабра:
«Если ты хочешь использовать композицию функций, где фунция имеет два аргумента», говорит Шерлок, «тебе нужно (.).(.)!”»
«Это похоже на испуганную сову», восклицает Ватсон
Мы так близки к линзам! «Ммм я почти общущаю вкус линз Ватсон» расплывается от счастья Шерлок. «Линзы позволяют тебе выполнять композицию функций, fold и обходы (traversals) вместе. Я чувствую как функторы и fold -ы перемешиваются во рту прямо сейчас!»
Здравствуйте у меня вопрос, при использовании cgroups возможно добавлять свой release notify agent (простой баш скрипт), вопрос, существуют ли ограничения на возможности этого скрипта. Т.к. я заметил, что я не могу перенести процесс (и прочие процессы отфоркивающиеся от него) в не root цгруппу в любом контроллере. При этом не ясно почему, поскольку данный процесс в ps выглядит как обычный, у него не realtime scheduler (т.к. у меня в ядре нет поддержки cgroups для realtime процессов). Сам же lock на цгруппы снимается при запуске скрипта, и потом выставляется назад.
Есть ли у кого-нибудь идеи как отлаживать данную ситуацию.
Я конечно могу обойти этот вопрос, но это портебует наличия userspace демона, что хотелось бы обойти.
Очевидно, что на лор люди в технические темы не приходят. Поэтому неинтересные темы можно и удалять. А как узнать интересная ли тема? Просто, есть подписавшиеся - интересная, нет - не интересная.
Здравствуйте, у меня следющий вопрос как мне добавить хук на за изменениями статуса сервисов в системах инициализации. Интересуют systemd, upstart, реализации init в debian и можно слаке.
P.S. решение для openrc я знаю, но если хотите рассказать, то можете.
P.P.S попрошу воздержаться от не относящихся к созданию хуков/управлению сервисами холиваров.
Спасибо.
Дополнительные требования к сервисам и хукам могу сформировать если необходимо.
Сейчас на LOR существует очень неудобная ситуация с тем, что в случае игнорирования пользователя игнорируется вся ветвь ответов на его комментарии, в итоге треды в Development становится невозможно читать.
Можно ли это решить каким-нить из следующих вариантов:
игнорировать только один уровень комментариев, т.е. игнорируемого и прямые ответы на него, и показывать остальные (начиная с ответов на ответы).
добавить unignore, т.е. список пользователей, комментарии которых не игнорируются даже в случае если они находятся в игнорируемой подветви.
P.S. Про мнени запили сам/давай патчи и т.п., я бы сначала хотел услышать мнение администрации и возможно другие варианты решения этой проблемы.
P.P.S. варианты «вдоль» и выложи пароль тоже рассматриваются.
Как известно, принято официальное решение перевести дистрибутив gentoo [1] на современную систему инициализации systemd [2]. В связи с этим разработчики разделились на две группы:
не согласные с переходом на systemd, которые собираются создавать новый дистрибутив eGentoo на основе базы. Gentoo,
поддерживающие новую политику
Пользователям беспокоиться не о чем, поскольку дистрибутивы будут совместимы и по возможности будут использовать общее дерево.
Однако с связи с тем, что поддерживать systemd в дистрибутиве достаточно сложно, т.к. нужно поддерживать большое количество патчей, которые не принимаются апстримом и в связи с тем, что исходных код systemd во многом оставляет желать лучшего, то принято решение не держать отдельный репозиторий с патчами, а начать новый проект по включению systemd в eudev - eSystemd. Официального анонса пока нет, и разработчики собирают идеи и первостепенные задачи, на которые надо будет обратить внимание, и через неделю ждите новости с LKML.
В проекте gentoo-linux оживляется добрая традиция Дня Бага, в этот день любой человек может помочь в исправлении ошибок. В каждую первую субботу месяца, в течение 24 часов, на канале #gentoo-bugs @ Freenode, вы можете принять участие в этом мероприятии, целью которого является успешное закрытие максимального количества багов.
Требования к тем, кто хочет поучаствовать:
Установленная система Gentoo, на реальном железе или в виртуальной машине.
IRC-клиент, чтобы присоединиться к каналам #gentoo-bugs, #gentoo-dev-help (помощь по ебилдам) и #gentoo-wiki (помощь по вики).
Спустя более года относительно активной разработки, команда разработчиков представила xmonad 0.11!
XMonad — это тайлинговый менеджер окон, который известен своей лёгкостью, надёжностью, расширяемостью и эффективностью. Он поддерживает настоящий многопоточный тайлинг, у него богатые и простые возможности настройки. Легко портируем, работает на обычных десктопах, ноутбуках, нетбуках, телефонах, игровых консолях, OLPC и т.п.
Возможности:
автоматическое управление окнами;
основное управление с помощью клавиатуры: мышь не нужна;
полная поддержка тайлинг окон на multi-head дисплеях;
полная поддержка плавающих окон, табов и декораций окон;
полная поддержка утилит Gnome и KDE;
поддержка XRandr для поворотов, добавления и удаления мониторов;
поддержка композитинга;
большая библиотека расширений;
отличная документация;
большая и активная команда разработчиков, поддержки и сообщество.
Наконец-то исправлена ошибка #177 (фокус в Java-приложениях).
Можете ли вы поделиться примерами реальной жизни, где вы напрямую пользовались возможносяти cgroup cpusets (использование их для различных контейнеров, которое делается автоматически врапперами типа libvirt не в счёт).
а кроме этого ещё пара фиксов, вот так надо расправляться с пакетами, которые masked for removal, а не начинать плакаться на форумах и гнать на девелоперов.