Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Aleksey Danilevsky
    @alexd1971

    Добрый день! Не знаю в какой раздел обратиться, но поскольку я пока в Haskell полный чайник, задам вопрос здесь.
    Пытаюсь следовать описанным quick start шагам, описанным здесь: http://haskell.vacationlabs.com/en/latest/docs/reflex/getting-started.html. Но получаю ошибку при компиляции пакета happy. Пытаюсь установить happy через stack install happy и получаю такое:

    happy> Configuring happy-1.19.5...
    happy> build
    happy> Building happy-1.19.5...
    happy> Preprocessing executable 'happy' for happy-1.19.5...
    happy> setup: The program 'happy' is required but it could not be found

    То есть получается, что установить happy нельзя, потому что не установлен happy. Что я делаю не так?

    Yuriy Syrovetskiy
    @cblp
    собрать happy нельзя, потому что не установлен happy
    хотя у меня собирается свежий happy без готового себя
    попробуйте stack --resolver=lts-14.20 install happy
    Aleksey Danilevsky
    @alexd1971
    Вроде бы так сработало. Спасибо
    Yuriy Syrovetskiy
    @cblp
    значит, у вас в глобальном проекте ~/.stack/global-project/stack.yaml слишком старый резолвер. советую поменять на свежий, например lts-14.20
    Aleksey Danilevsky
    @alexd1971
    А когда я запускаю stack install в каталоге проекта, то он использует какой резолвер? Который прописан глобально или, который прописан в stack.yaml проекта?
    Yuriy Syrovetskiy
    @cblp
    ого, у вас lts <= 9.2, Published on 2017-08-27
    когда запускаете stack в проекте, используется резолвер проекта, написанный явно в его конфиге. stack-проекта без явного резолвера не может быть
    Aleksey Danilevsky
    @alexd1971
    Я взял проект по ссылке http://haskell.vacationlabs.com/en/latest/docs/reflex/getting-started.html и пытаюсь его собрать. В нем вот что:
    resolver: lts-7.8
    
    packages:
    - .
    
    extra-deps:
    - ghcjs-dom-0.7.0.3
    - ghcjs-dom-jsaddle-0.7.0.3
    - jsaddle-0.7.0.0
    - jsaddle-dom-0.7.0.3
    - jsaddle-warp-0.7.0.0
    - prim-uniq-0.1.0.1
    - ref-tf-0.4.0.1
    - zenc-0.1.1
    - git: https://github.com/reflex-frp/reflex
      commit: 91299fce0bb2caddfba35af6608df57dd31e3690
      # Latest develop comment at the time of writing
    - git: https://github.com/hamishmack/reflex-dom
      commit: d9842742183a800cf1f98f89d42d849d52dd2d67
      # Latest develop comment at the time of writing
    
    flags: {}
    
    extra-package-dbs: []
    Aleksey Danilevsky
    @alexd1971
    Будет ли ошибкой, если я в stack.yaml проекта подниму версию резолвера?
    Yuriy Syrovetskiy
    @cblp
    если у вас есть проект с resolver: lts-7.8, то глобально установленный happy поможет собрать happy в проекте
    Aleksey Danilevsky
    @alexd1971
    Да так и получилось
    Yuriy Syrovetskiy
    @cblp

    Будет ли ошибкой, если я в stack.yaml проекта подниму версию резолвера?

    @alexd1971, это будет не ошибкой, а изменением исходного кода. может повлечь изменения в других частях проекта

    Aleksey Danilevsky
    @alexd1971
    Этот файл все равно пришлось править, так как в нем был устаревший формат указания зависимостей
    Yuriy Syrovetskiy
    @cblp
    ну, это не проблема
    а если поднимете резолвер, это будет означать поднятие версий многих зависимостей
    а у них мог измениться API за это время
    или даже исчезнуть фичи, используемые в этом проекте
    Aleksey Danilevsky
    @alexd1971
    Ок, понял, спасибо.
    Yuriy Syrovetskiy
    @cblp
    это редко случается, но возможно
    Aleksey Danilevsky
    @alexd1971
    Добрый день. Хотел пройти lens tutorial (https://hackage.haskell.org/package/lens-tutorial-1.0.4/docs/Control-Lens-Tutorial.html). Делаю так:
    1. stack install lens-tutorial
    2. stack ghci
    3. import Control.Lens.Tutorial
      Получаю:
      <no location info>: error:
       Could not find module ‘Control.Lens.Tutorial’
       It is not a module in the current program, or in any known package.
      В рассылке по такой проблеме нашёл рекомендацию запускать ghci так:
      stack exec -- ghci
      Попробовал - не помогло, ошибка та же.
      Подскажите, пожалуйста, как же все таки импортировать этот модуль?
    Yuriy Syrovetskiy
    @cblp
    stack install не нужен
    для библиотек установка не имеет смысла
    использовать библиотеки в репле надо так
    stack ghci --package=lens-tutorial
    stack exec -- ghci по сути от stack ghci не отличается
    Aleksey Danilevsky
    @alexd1971
    @cblp Спасибо, заработало
    nponeccop
    @nponeccop

    stack install не нужен

    Не нужен, но вместо него нужен stack build. Иначе откуда ghci его возьмёт. package нужен только если пускаем без stack.yml, иначе stack вроде бы все пекеджи дописывает в --package, в этом и смысл stack repl

    для библиотек установка не имеет смысла

    Нуу, для динамических наверное имеет. Но они погнили и там вообще ад всегда был. Поэтому все, кроме особо упоротых типа Арча, линкуют статикой.

    Yuriy Syrovetskiy
    @cblp
    @nponeccop stack ghci сам скачает и соберёт (и установит в смысле ghc-pkg) любую библиотеку, указанную в --package
    @nponeccop нет, cabal install и stack install вообще ничего не делают с библиотеками, они только бинарники программ копируют
    Yuriy Syrovetskiy
    @cblp
    stack ghci подключает к сеансу не все библиотеки, а только те, что в зависимостях у выбранного компонента (или компонента по умолчанию), так что даже в проекте бывает нужен ключ --package
    dfr
    @deflexor_twitter
    привет, тут такое странное хочется сделать, вот есть 2 типа дерева:
    data Elem = Tag { tagChildren :: [Elem] }
                | RootTag [Elem]
                | Comment
                deriving (Eq, Read, Show)
    
    data Elem1 = Tag [Elem]
                | Root [Elem]
                | Comment
                deriving (Eq, Read, Show)
    есть уже созданное дерево Elem, но хочется сделать из него Elem1 той же структуры, видно что элементы там легко заменяемы. По идее хотелось бы просто deriving Functor, или может Traversable ? Но они хотят параметр типа, а тут он мне в общем и не нужен, как-нибудь еще можно сделать ?
    Yuriy Syrovetskiy
    @cblp

    @deflexor_twitter функторы сохраняют форму, меняя содержимое, а вам надо наоборот, если я правильно понял, — поменять форму, оставить содержимое.

    в общем случае форму надо менять руками, но если ваши типы по структуре совпадают, то можно отбросить конкретные имена конструкторов с помощью дженериков

    {-# LANGUAGE DeriveAnyClass #-}
    {-# LANGUAGE DeriveGeneric  #-}
    
    import qualified Generics.SOP as SOP
    import qualified GHC.Generics as GHC
    
    data Elem
        = Tag { tagChildren :: [Elem] }
        | RootTag [Elem]
        | Comment
        deriving (Eq, GHC.Generic, SOP.Generic, Read, Show)
    
    data Elem1
        = Tag1 [Elem]
        | Root1 [Elem]
        | Comment1
        deriving (Eq, GHC.Generic, SOP.Generic, Read, Show)
    
    upgrade :: Elem -> Elem1
    upgrade = SOP.to . SOP.from
    
    example :: Elem
    example = RootTag [Tag [], Comment]
    
    -- $> upgrade example
    
    -- Root1 [Tag {tagChildren = []},Comment]
    dfr
    @deflexor_twitter
    Спасибо, это круто что так можно, надо поизучать что за SOP
    Yuriy Syrovetskiy
    @cblp
    SOP — это самые простые дженерики
    дженерики — это обобщённое представление ADT в виде «какая-то сумма» или «какое-то произведение»
    dfr
    @deflexor_twitter
    Еще такой вопрос, можно ли расширить тип Elem например, т.е. в каждый конструктор добавить поле или может какой-то оберткой, видимо тоже только дженериками ?
    Yuriy Syrovetskiy
    @cblp
    можно расширить тип, изменив его определение
    или что вы хотите? можете сформулировать кодом или псевдокодом?
    dfr
    @deflexor_twitter

    ну те был например такой тип:

    data Elem = Tag { tagChildren :: [Elem] }
                | RootTag [Elem]
                | Comment
                deriving (Eq, Read, Show)

    а станет такой:

    data Sel = True | False | NotSure
    data Elem = Tag Sel { tagChildren :: [Elem] }
                | RootTag Sel [Elem]
                | Comment Sel
                deriving (Eq, Read, Show)
    Yuriy Syrovetskiy
    @cblp
    и вам нужен какой-то автоматический способ сконвертировать V1.Elem в V2.Elem? я такого не знаю, я писал бы руками
    Tag Sel { tagChildren :: [Elem] } нельзя писать. можно Tag { tagSel :: Sel, tagChildren :: [Elem] }
    nponeccop
    @nponeccop

    Гуглите expression problem, всякие вопросы расширения и декорирования там решены

    https://serokell.io/blog/introduction-tagless-final -- это один из примеров того что гуглится

    Но мы уже выходим за рамки новиса )
    nponeccop
    @nponeccop

    Одна из идей это вынести рекурсивную структуру в функтор

    data Elem a = Tag { tagChildren :: [a] }
                | RootTag [a]
                | Comment

    И в таком виде легче декорировать. Общая идея что был Fix (\a -> Elem a) а станет Fix (\a -> Elem (Sel, a)). Но в лоб так сделать нельзя поскольку нет таких типовых лямбд и нужны приседания (которые уже придуманы в разных вариантах; у меня псевдокод, реально там Fix Elem конечно).

    Yuriy Syrovetskiy
    @cblp
    Elem (Sel, a) не похоже на задачу
    nponeccop
    @nponeccop
    data X a = X Sel (Elem a) deriving (Functor)
    data Y = Fix X
    Y у нас изоморфен декорированному варианту Elem (так как Sel в каждой ветке). Вот этому
    data Elem = Tag Sel { tagChildren :: [Elem] }
                | RootTag Sel [Elem]
                | Comment Sel
    Yuriy Syrovetskiy
    @cblp
    есть ещё подход с полями-расширителями, кажется, он назывался trees that grow:
    data Elem tagExtraField rootExtraField commentExtraField extraVariant
        = Tag { tagChildren :: [Elem], tagExtra :: tagExtraField }
        | RootTag [Elem] rootExtraField
        | Comment commentExtraField
        | ExtraVariant extraVariant
    
    type ElemV1 = Elem () () () Void
    
    data Sel = True | False | NotSure
    
    type ElemV2 = Elem Sel Sel Sel Void
    nponeccop
    @nponeccop
    Там вариантов вагон и маленькая тележка, да. Надо подбросить товрищу ключевых слов только как это искать. По-моему у Олега есть серия целая на эту тему