#haskell #scrypt #io-monad
#haskell #scrypt #io-монада
Вопрос:
* Извините за основной вопрос, только начал изучать Haskell.
Я пытаюсь написать функцию, которая получит строку и вернет зашифрованный хэш.
На данный момент я пришел к следующему:
encrypt :: ByteString -> ByteString
encrypt = do
x <- Crypto.Scrypt.encryptPassIO' (Pass "secret")
fmap Crypto.Scrypt.getEncryptedPass x
Однако я получаю сообщение об ошибке:
• Couldn't match expected type ‘ByteString’
with actual type ‘IO ByteString’
• In a stmt of a 'do' block: x <- encryptPassIO' (Pass plain)
In the expression:
do { x <- encryptPassIO' (Pass plain);
fmap Crypto.Scrypt.getEncryptedPass x }
In an equation for ‘encrypt’:
encrypt plain
= do { x <- encryptPassIO' (Pass plain);
fmap Crypto.Scrypt.getEncryptedPass x }
Есть идеи, как я могу избавиться от ввода-вывода?
Спасибо!
Комментарии:
1. Вы не можете избавиться от ввода-вывода (без использования darkest magic или путем вызова другого библиотечного метода). Скорее исправьте свой тип:
ByteString -> IO ByteString
2. О … хорошо. Как мне сохранить значение в базе данных? Т.е. далее у меня есть
execute "INSERT INTO test VALUES ...
то, с чем я хочу использовать зашифрованное значение.3. Если это дальше по строке
IO
также является операцией, просто поместите их оба вdo
выражение.
Ответ №1:
Вместо того, чтобы избавляться от IO
, вам нужно настроить encrypt
возврат an IO ByteString
. encryptPassIO'
для соли нужны случайные данные, которые она получает от IO
монады, поэтому вы застряли там.
import Crypto.Scrypt (encryptPassIO', getEncryptedPass)
encrypt :: ByteString -> IO ByteString
encrypt = fmap getEncryptedPass . encryptPassIO' . Pass
Вместо do
обозначения я использовал encryptPassIO' . Pass
для получения IO EncryptedPass
значения из аргумента. Затем мы используем fmap
для подъема getEncryptedPass :: EncryptedPass -> ByteString
в IO
монаду.
Вы могли бы использовать do
нотацию, но IMO fmap
делает это более чистым:
encrypt pass = do
x <- encryptPassIO' pass
return (getEncryptedPass x)