lstmDiff :: forall n m. (Monad m, KnownNat n) => Diff m (Blob (2*n), (Blob n, Blob (4*n))) (Blob n, Blob n)
lstmDiff = Diff run
  where
    run (par, (hidden, inputs)) =
      let (new_h, new_y, store) = (lstmForward n (getBlob par)
                                   (getBlob hidden)
                                   (getBlob inputs))
          backward (dh, dy) = let (d_ws, d_hs, d_xs) = (lstmBackward n (getBlob par)
                                                        store (getBlob dh) (getBlob dy))
                              in return (blob d_ws, (blob d_hs, blob d_xs))
      in return ((blob new_h, blob new_y), backward)

    n :: Int
    n = fromIntegral (natVal (Proxy :: Proxy n))
lstmDiff :: forall n m. (Monad m, KnownNat n) => Diff m (Blob (2*n), (Blob n, Blob (4*n))) (Blob n, Blob n)
lstmDiff = Diff run
  where
    run (par, (hidden, inputs)) =
      let (new_h, new_y, store) = (lstmForward n (getBlob par)
                                   (getBlob hidden)
                                   (getBlob inputs))
          backward (dh, dy) = let (d_ws, d_hs, d_xs) = (lstmBackward n (getBlob par)
                                                        store (getBlob dh) (getBlob dy))
                              in return (blob d_ws, (blob d_hs, blob d_xs))
      in return ((blob new_h, blob new_y), backward)

    n :: Int
    n = fromIntegral (natVal (Proxy :: Proxy n))
lstmDiff = Diff run
  where
    run (par, (hidden, inputs)) =
      let (new_h, new_y, store) = (lstmForward n (getBlob par)
                                   (getBlob hidden)
                                   (getBlob inputs))
          backward (dh, dy) = let (d_ws, d_hs, d_xs) = (lstmBackward n (getBlob par)
                                                        store (getBlob dh) (getBlob dy))
                              in return (blob d_ws, (blob d_hs, blob d_xs))
      in return ((blob new_h, blob new_y), backward)

    n :: Int
    n = fromIntegral (natVal (Proxy :: Proxy n))