Ответы пользователя по тегу Haskell
  • Как порождать двоичные векторы в Haskell?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    Если подключить Control.Monad, то все возможные двоичные векторы, представленные списком компонент, порождаются функцией
    vectors :: Int -> [[Int]]
    vectors n = replicateM n [0, 1]

    Вместо [0,1] могут быть любые другие значения компонент (True и False, например). Аргумент n задаёт длину векторов, которое будет равняться числу переменных в логическом выражении.

    upd.
    С учётом пожеланий новый вариант:
    data BinTree = Leaf [Int] | Node BinTree BinTree deriving Show
    vars :: Int -> [Int] -> BinTree
    vars 1 context = Node (Leaf (0:context)) (Leaf (1:context))
    vars n context = Node (vars (n-1) (0:context)) (vars (n-1) (1:context))
    
    Prelude> vars 2 []
    Node (Node (Leaf [0,0]) (Leaf [1,0])) (Node (Leaf [0,1]) (Leaf [1,1]))
    Ответ написан
    5 комментариев
  • Как отнять UTCTIme от UTCTime и получить разницу в днях?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    Самый лобовой способ состоит в использовании diffTimeToPicoseconds с последующим делением на некий коэффициент, равный числу пикосекунд в сутках.
    Ответ написан
    1 комментарий
  • Как из даты,которую ввёл пользователь,отнять текущую дату?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    сравнить две даты [...] отнимать текущую дату - и получаю разницу в днях. И эта разница должна быть не более чем 16 То есть дата от пользователя должна быть не раньше текущей (чтобы не улететь в прошлое), но не позже чем "текущая + 16 дней"

    -- количество дней (но не меньше 0 и не больше 16) от сего дня (today) до указанного дня (day)
    -- возвращаемое число лежит в интервале [0, 16]
    strippedDayDiff :: Day -> Day -> Integer
    strippedDayDiff day today = let d = diffDays day today in if d > 16 then 16 else if d < 0 then 0 else d

    Использование:
    if strippedDayDiff forecastDay (utctDay currentTime) >= ...

    Если нужно проверить, что разница лежит ровно в диапазоне [0, 16], то
    diffDaysIn0_16 day today = let d = diffDays day today in 0 <= d && d <= 16


    P.S. Сергей, там есть более узкоспециализированные функции. Думаю, основная проблема изначально состояла в том, что в коде не были проставлены типы и/или выбор возвращаемых значений не соответствует поставленной устно задаче.
    Ответ написан
    Комментировать
  • Как можно доработать функцию для собственного типа?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    при вводе getByTypes [MyInt, MyString] base выдает ["first","next","str"]
    Значит, функция работает.

    если в качестве аргумента задать MyStruct , то выдает ошибку , как сделать так чтоб функция работала с этим типом ?
    Как происходит вызов?
    getByTypes [MyStruct[("s1",MyInt),("s2",MyDouble)]] base
    Ответ написан
    3 комментария
  • Сопоставление с образцом( Haskell )?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    В Haskell в отличие от, например, Wolfram Mathematica в перечне образцов в рамках одного случая каждая переменная может быть использована только единожды.
    На самом деле образцы являются краткой формой записи системы проекций для произведений-типов и разбора случаев для сумм-типов.
    Например,
    substitute x y [] = ...
    substitute x y (h:hs) = ...
    является краткой формой записи (кстати, "упрощенный" Хаскель, к которому ghc приводит код перед компиляцией, как раз такое представление использует)
    substitute x y z = case z of
      [] -> ...
      (h:hs) -> ...
    или, если гиперболизировать,
    substitute x y z = if null z then ... else let h = head z; hs = tail z in ...

    Основная мысль: все переменные в образцах принципиально обязаны быть разными в общем случае.
    Например, как быть с func x x = ..., когда x :: a -> b?
    Исключение есть всего одно: когда тип обеих переменных имплементирует Eq. Но современный Haskell этого ещё не умеет. Возможно, в будущем такая фишка будет добавлена как одно из многочисленных расширений языка.
    Ответ написан
    2 комментария
  • Как измерить время выполнения функции в Haskell?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    Прокомментирую только приведённый код.

    Во-первых, в многоаргументных функциях $! нужно делать не только на внешнем уровне, но и на всех остальных, т.е. (f $! x) $! y, иначе строгость относится только к первому аргументу и созданию
    чанка.

    Во-вторых, компилятор хитёр, но один из вариантов его обдурить заключается в оборачивании вычисляемого выражения в хитрую монаду. Хитрее IO придумать сложно.
    import Data.Time
    
    testTime n func arg1 arg2 = let
      list = (replicate $! n) $! (arg1, arg2)
      func' ~(x, y) = return $ (func $! x) $! y
      in do
        start <- getCurrentTime
        sequence $ (map $! func') $! list
        stop <- getCurrentTime
        print (diffUTCTime stop start)
    Ответ написан
    Комментировать
  • Что использовать в haskele для работы с матрицами?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    Есть поисковик hoogle:
    hoogle.haskell.org/?hoogle=%3A%3A+%5B%5Ba%5D%5D+-%...
    он предлагает функцию transpose из модуля Data.List.

    Если у Вас матрица не список списков, а что-то другое, уточните.
    Ответ написан
    Комментировать
  • Как заменить пару символы на драгие пары символов в строке?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    Однострочник
    f :: String -> String -> String -> String
    f str a b = let n = length a in if take n str == a then b ++ f (drop n str) a b else if str == "" then "" else head str : f (tail str) a b

    Свойства решения: ленивое, работает с бесконечными строками, заменяет первое вхождение подстроки a на b в случае неоднозначной замены (напр., f "aaa" "a" "b" == "ba"), временная сложность O(N) по N = length(str).
    Что можно улучшить: 1) обработка хвоста длины < length(b), 2) оформить код как многострочную читаемую функцию, 3) выделить функцию \s -> f s a b как локальную или даже поменять исходных порядок аргументов.
    Ответ написан
  • Как реализуется GUI на чистом функциональном языке без состояния (например, на Haskell)?

    youngmysteriouslight
    @youngmysteriouslight
    ТК, ТТ, JS, FP, WM
    Для любого языка имеются библиотеки, написанные на более низком уровне. Для одних языков их больше, для других — меньше.
    Как делаются библиотеки под Haskell я не знаю, но Вас интересует именно аспект, связанный с сохранением чистоты при работе с GUI. На уровне использования языка, сохранить чистоту можно, оборачивая все «нечистые» вычисления в монады, например, в IO. Удобно использовать представление, которое в математике называется категорией Клейсли, когда «нечистая» функция A -> B превращается в чистую A -> IO B. Примеры привёл egorinsk комментарием выше.
    Ответ написан