Conversion of a simple Python Neural Network to a Haskell implementation
You often switch between matrices and lists in the dotp function. Since that is an essential part of your code called every iteration and your data is a matrix, you should be using matrices everywhere.

In the documentation is noted, that there is a functor instance. That means you can use the function fmap on the matrix, which (in this case) maps a function over every cell. This means you can swap map (map fromIntegral) with fmap fromIntegral. The equivalent to zipWith (zipWith ..) is called elementwise.

The generations function doesn't seem to be called: you can avoid having dead code by compiling with warnings enabled, -Wall. The flipSign function is predefined and called negate.

I have changed nonlin to make the variable explicit, otherwise it wouldn't be clear what this Bool actually does. Furthermore, I have added some comments.

Finally, I have changed nextGeneration as there is no need to carry the l1 variable if it isn't needed by the next step. I've extracted that into a function (and so have to take the 9999th iteration in main).

Here is my version of the code:

import System.Random (randoms, mkStdGen)
import Data.Matrix

-- | input dataset
sample :: Matrix Double
sample = fmap fromIntegral $ fromLists
    [ [0,0,1]
    , [0,1,1]
    , [1,0,1]
    , [1,1,1]
    ]

-- | output dataset
answers :: Matrix Double
answers = transpose (fmap fromIntegral output)
    where
        output = fromLists [[0,0,1,1]]

-- | sigmoid function
nonlin :: Bool -&gt; Double -&gt; Double
nonlin derivative x = if derivative then x * (1.0 - x)
                                    else 1.0 / (1.0 + (exp (negate x)))

layer1 :: Matrix Double -&gt; Matrix Double -&gt; Matrix Double
layer1 l0 syn0 = fmap (nonlin False) (multStd l0 syn0)

nextGeneration :: Matrix Double -&gt; Matrix Double
nextGeneration syn0 = new_syn0
    where
        -- forward propagation
        l1 = layer1 sample syn0

        -- how much did we miss?
        l1_error = elementwise (-) answers l1

        -- multiply how much we missed by the
        -- slope of the sigmoid at the values in l1
        l1_delta = elementwise (*) l1_error (fmap (nonlin True) l1)

        -- update weights
        new_syn0 = elementwise (+) syn0 (multStd (transpose sample) l1_delta)

main = do
    putStrLn "Output After Training:"
    print (layer1 sample result)
        where
            start = fromList 3 1 (randoms (mkStdGen 42))
            generations = iterate nextGeneration start
            result = generations !! 9999