Haskell передает потоком с эффектами IO

Вы можете использовать DatetimeIndex объекты из пакета pandas следующим образом:

import pandas as pd


# create DatetimeIndex objects with *seconds* resolution
dtidx1 = pd.date_range('15:30:43', '16:30:56', freq='S')
dtidx2 = pd.date_range('15:40:35', '15:50:20', freq='S')

# use the DatetimeIndex.intersection method to get another 
# DatetimeIndex object whose values are what you requested
dtidx1.intersection(dtidx2)
11
задан Geoff 16 April 2009 в 19:54
поделиться

3 ответа

Как насчет этого кода:

import IO

normalStreamFunc :: [String] -> [String]
normalStreamFunc (x:xs) = reverse(x) : normalStreamFunc xs

effectfulStreamFunc :: [String] -> [IO (String)]
effectfulStreamFunc [] = []
effectfulStreamFunc (x:xs) =
    let rest = effectfulStreamFunc xs in
        (putStrLn x >> return x) : rest

main :: IO ()
main = do
     let fns = ["a", "b", "c", "d"]
     let appliedFns = effectfulStreamFunc fns
     pieces <- sequence $ take 2 appliedFns
     print $ show $ pieces

Вместо effectfulStreamFunc фактически выполняет какой-либо ввод-вывод, вместо этого создается список ввода-вывода действия для выполнения. (Обратите внимание на изменение сигнатуры типа.) Затем основная функция выполняет 2 из этих действий, выполняет их и печатает результаты:

a
b
"[\"a\",\"b\"]"

Это работает, потому что тип IO (String) является просто функцией / значением, подобным любые другие, которые вы можете поместить в список, передать их и т. д. Обратите внимание, что синтаксис do не встречается в «effectfulStreamFunc» - на самом деле это чистая функция, несмотря на «IO» в ее сигнатуре. Только когда мы запускаем sequence для тех, кто в основном, эффекты действительно происходят.

7
ответ дан 3 December 2019 в 10:05
поделиться

Я не совсем понимаю вашу главную цель, но использование putStrLn приводит к оценке всего списка, потому что он оценит аргумент при выполнении. Рассмотрим

import IO

normalStreamFunc :: [String] -> [String]
normalStreamFunc (x:xs) = reverse(x) : normalStreamFunc xs

effectfulStreamFunc :: [String] -> IO [String]
effectfulStreamFunc [] = return []
effectfulStreamFunc (x:xs) = do
    rest <- effectfulStreamFunc xs
    return (reverse(x):rest)

main :: IO ()
main = do
     let fns = ["a", "b", undefined,"c", "d"]
     es <- effectfulStreamFunc fns
     print $ show $ take 2 es

, что это приводит к "[\" a \ ", \" b \ "]", а при использовании версии putStrLn это приводит к исключению.

2
ответ дан 3 December 2019 в 10:05
поделиться

Как упоминал Том, вы не можете сделать это «безопасно», потому что вы нарушаете ссылочную прозрачность в Haskell. Вы пытаетесь выполнить побочные эффекты лениво, но лень заключается в том, что вам не гарантируется, в каком порядке и будут ли результаты оценены, поэтому в Haskell, когда вы говорите ему выполнить побочный эффект, он всегда выполняется, и в точном указанном порядке. (т.е. в этом случае побочные эффекты от рекурсивного вызова effectfulStreamFunc до возвращают , потому что это был порядок, в котором они были перечислены) Вы не можете сделать это лениво, не используя unsafe.

Вы можете попробовать использовать что-то вроде unsafeInterleaveIO , именно так ленивый ввод-вывод (например, hGetContents ) реализован в Haskell, но у него есть свои проблемы; и вы сказали, что не хотите использовать «небезопасные» вещи.

import System.IO.Unsafe (unsafeInterleaveIO)

effectfulStreamFunc :: [String] -> IO [String]
effectfulStreamFunc [] = return []
effectfulStreamFunc (x:xs) = unsafeInterleaveIO $ do
    putStrLn x
    rest <- effectfulStreamFunc xs
    return (reverse x : rest)

main :: IO ()
main = do
     let fns = ["a", "b", "c", "d"]
     es <- effectfulStreamFunc fns
     print $ show $ take 2 es

В этом случае результат выглядит так

"a
[\"a\"b
,\"b\"]"
1
ответ дан 3 December 2019 в 10:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: