最后学习如何在Haskell中使用monad!
我想阅读文件testInput
,删除第一行,将函数waffles
应用于其他所有行,并将结果保存到文件output.txt
中。
我写了以下代码:
main = do
contents <- tail . fmap lines . readFile $ "testInput"
result <- fmap waffles contents
writeFile "output.txt" $ concat result
waffles row col = (row - 1)*(col - 1)
可悲的是,编译器抱怨道:
waffles.hs:3:41:
Couldn't match type ‘IO String’ with ‘[String]’
Expected type: FilePath -> [String]
Actual type: FilePath -> IO String
In the second argument of ‘(.)’, namely ‘readFile’
In the second argument of ‘(.)’, namely ‘fmap lines . readFile’
waffles.hs:5:9:
Couldn't match expected type ‘[b]’ with actual type ‘IO ()’
Relevant bindings include program :: [b] (bound at waffles.hs:2:1)
In a stmt of a 'do' block: writeFile "output.txt" $ concat result
In the expression:
do { contents <- tail . fmap lines . readFile $ "testInput";
result <- fmap waffles contents;
writeFile "output.txt" $ concat result }
In an equation for ‘program’:
program
= do { contents <- tail . fmap lines . readFile $ "testInput";
result <- fmap waffles contents;
writeFile "output.txt" $ concat result }
Failed, modules loaded: none.
我发现这个错误非常令人生畏。你能帮我调试一下吗?
我也很感激代码风格的建议!
编辑:我忘了拆分文件的行并将它们转换为整数。我尝试解决如下问题:main = do
contents <- tail . fmap lines . readFile $ "testInput"
contents <- fmap read . words contents
result <- fmap waffles contents
writeFile "output.txt" $ concat result
waffles row col = (row - 1)*(col - 1)
但这只会引入更多令人困惑的编译器错误。
答案 0 :(得分:4)
import keras.backend as K
def customLoss(yTrue,yPred):
create operations with yTrue and yPred
- yTrue = the true output data (equal to y_train in most examples)
- yPred = the model's calculated output
- yTrue and yPred have exactly the same shape: (batch_size,output_dimensions,....)
- according to the output shape of the last layer
- also according to the shape of y_train
all operations must be like +, -, *, / or operations from K (backend)
return someResultingTensor
语句中的第一行失败,因为您尝试在do
上使用tail
。您需要IO [String]
fmap
函数:
tail
现在您需要一种方法来从contents <- fmap tail . fmap lines . readFile $ "testInput"
-- or....
contents <- fmap (tail . lines) . readFile $ "testInput"
获取所有其他行。您可以为此定义一个简单的contents
函数:
everyOther
现在你可以将它链接到第一行的everyOther :: [a] -> [a]
everyOther (x:_:xs) = x : everyOther xs
everyOther _ = []
:
fmap
您contents <- fmap (everyOther . tail . lines) . readFile $ "testInput"
的{{1}}函数似乎与我认为的类型签名不相关。尝试从类型签名开始并从其中构建waffles
。根据您的描述,您只是为函数提供其他所有行,因此它应该具有签名:
(row - 1)*(col - 1)
鉴于waffles
的类型签名,您可以通过以下方式应用它:
waffles :: String -> String
输出中还有一件事:waffles
会将所有线条混合在一起。您可能希望在那里使用换行符,因此您可能希望使用let result = fmap waffles contents
代替。
concat