我完全陷入了困境,我觉得我现在可以使用一些帮助,只是为了保持理智。我想要一些简单的事情,就像为返回Maybe
的函数添加日志记录功能一样简单,但无论我怎么努力,我都无法获得正确的类型。
这是(我认为)最接近的:
import Data.Maybe
import Control.Monad
import Control.Monad.Writer
q :: Integer -> Maybe Integer
q x = if x > 7
then Just x
else Nothing
qlog :: Integer -> WriterT [String] Maybe Integer
qlog x = do
tell ["Querying " ++ show x]
return $ q x
这仍然让我输入错误:
Couldn't match type ‘Maybe Integer’ with ‘Integer’
Expected type: WriterT [String] Maybe Integer
Actual type: WriterT [String] Maybe (Maybe Integer)
In a stmt of a 'do' block: return $ q x
In the expression:
do { tell ["Querying " ++ show x];
return $ q x }
In an equation for ‘qlog’:
qlog x
= do { tell ["Querying " ++ show x];
return $ q x }
我应该如何调整代码以使其编译和工作?
非常感谢你的帮助,Haskellers同事!
答案 0 :(得分:3)
为了进行类型检查,内部monad应为lifted:
Public Sub FormulaGenerator()
Dim ws As Worksheet
Dim firstRow As Long
Dim lastRow As Long
Dim dateRange As Range
Dim cell As Range
Dim hitList As Collection
Dim refMonth As Integer
Dim thisMonth As Integer
Dim r As Long
Dim output() As Variant
Dim item As Variant
'Set these for your own task.
Set ws = ThisWorkbook.Worksheets("Sheet1")
firstRow = 3
lastRow = 20
'Read the values cell by cell
Set dateRange = ws.Range(ws.Cells(firstRow, "A"), ws.Cells(lastRow, "A"))
Set hitList = New Collection
For Each cell In dateRange.Cells
item = cell.Month
thisMonth = Month(cell.Value)
If thisMonth <> refMonth Then
'It's a new month so populate the collection with the cell address
hitList.Add cell.Address(False, False)
refMonth = thisMonth
End If
Next
'Populate the output array values
ReDim output(1 To hitList.Count, 1 To 1)
r = 1
For Each item In hitList
output(r, 1) = "=MONTH(" & item & ")"
r = r + 1
Next
'Write the output array starting at cell "F2"
ws.Cells(2, "F").Resize(UBound(output, 1)).Formula = output
End Sub
因此,您需要写Public Sub OutputGenerator()
Dim ws As Worksheet
Dim firstRow As Long
Dim lastRow As Long
Dim dates As Variant
Dim hitList As Collection
Dim refMonth As Integer
Dim thisMonth As Integer
Dim r As Long
Dim output() As Integer
Dim item As Variant
'Set these for your own task.
Set ws = ThisWorkbook.Worksheets("Sheet1")
firstRow = 3
lastRow = 23
'Read the dates into an array
dates = ws.Range(ws.Cells(firstRow, "A"), ws.Cells(lastRow, "A")).Value
'Loop through the array to acquire each new date
Set hitList = New Collection
For r = 1 To UBound(dates, 1)
thisMonth = Month(dates(r, 1))
If thisMonth <> refMonth Then
'It's a new date so populate the collection with the month integer
hitList.Add thisMonth
refMonth = thisMonth
End If
Next
'Populate the output array
ReDim output(1 To hitList.Count, 1 To 1)
r = 1
For Each item In hitList
output(r, 1) = item
r = r + 1
Next
'Write the output array starting at cell "F2"
ws.Cells(2, "F").Resize(UBound(output, 1)).Value = output
End Sub
而不是lift :: (Monad m, MonadTrans t) => m a -> t m a
; return $ q x
;如:
lift $ q x