2014-12-29 4 views
2

Изучение основ Haskell IO Monads, я хотел бы создать дескриптор временного файла. Временный каталог FilePath находится в контексте IO, и мне нужно сопоставить функцию в этом контексте, чтобы присоединиться к пути с именем файла.Basic Haskell IO Monad FilePath join

Моя первая попытка состояла в использовании fmap, однако FilePath был объединен в обратном порядке. Возможно ли fmap без изменения порядка?

Моя вторая попытка работает, но она кажется слишком сложной. Любые предложения, как это можно улучшить?

Haskell - красивый.

import System.Directory(getTemporaryDirectory) 
import System.FilePath.Posix(joinDrive) 

-- fmap is simpler, but the join order was reversed 
createTempFile :: FilePath -> IO FilePath 
createTempFile filename = fmap (joinDrive filename) getTemporaryDirectory 

-- instead, I do this, but it feels overly complicated 
createTempFile' :: FilePath -> IO FilePath 
createTempFile' filename = getTemporaryDirectory >>= ((\x y -> return (joinDrive y x)) filename) 

ответ

5

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

createTempFile filename = fmap (flip joinDrive filename) getTemporaryDirectory 

Вы также можете использовать раздел:

createTempFile filename = fmap (`joinDrive` filename) getTemporaryDirectory 
+0

флип именно то, что мне нужно! Я считаю, что секционирование joinDrive превращает его в оператора - или что-то в этом роде. – indi

+0

@indi По существу, да. Вы не можете изменить свою фиксацию (насколько мне известно), но она позволяет вам использовать ее в нотации infix точно так же, как оператор, это очень удобный синтаксис. – bheklilr

5

Ваших первые результаты решения в обратном порядке присоединиться, потому что вы передаете filename в качестве первого аргумента joinDrive. Это может быть расширено, чтобы увидеть, что результат является правильным:

fmap (joinDrive filename) getTemporaryDirectory 

можно переписать с:

fmap (\f -> joinDrive filename f) getTemporaryDirectory 

, что это не то, что вы хотите. Что вам нужно, это то, что расширяется:

fmap (\f -> joinDrive f filename) getTemporaryDirectory 
в Haskell

вы можете написать это с помощью инфиксного обозначения:

fmap (`joinDrive` filename) getTemporaryDirectory 

Как примечание стороны, следует рассмотреть возможность использования </> вместо joinDrive, потому что getTemporaryDirectory Безразлично 't верните временный каталог с разделителем пути в конце: