Here's a solution for when you have one list and one scalar. Perhaps it can be adapted to your needs -- maybe I'll come back and edit it tailored to your use-case a little more later, but I think you'll get the point.
EDIT: Just saw that this post was from 2012; maybe I won't rush on tailoring it to your needs, but this post came up near the top in my Google search, so maybe somebody else will get some use out of these...
Method 1
Inner[MyFunction, {d}, {{a, b, c}}]
Inner[MyFunction, {{a, b, c}}\[Transpose], {d}, Reverse]
Output (they're equivalent) [leaving it to the reader to do it in the opposite order]:
{MyFunction[d, a], MyFunction[d, b], MyFunction[d, c]}
Method 2 - might be more adaptable for you:
Outer[MyFunction, {a, b, c}, {d}]
Output:
{{MyFunction[a, d]}, {MyFunction[b, d]}, {MyFunction[c, d]}}
Method 3
Distribute[MyFunction[{a, b, c}, d], List]
Output:
{{MyFunction[a, d]}, {MyFunction[b, d]}, {MyFunction[c, d]}}
Update -- GENERAL-CASE SOLUTIONS:
- These were also written to work with any combination of lists and scalars...
DistributeOp[distributeOver_] := Function[expr, Distribute[expr, distributeOver]]
EnsureList[expr_] := Flatten[{expr}, 1]
MapThreadRagged1[func_, a_, b_] := Inner[func, {EnsureList[a]}\[Transpose], {EnsureList[b]}]
MapThreadRagged2[func_, a_, b_] := Outer[func, EnsureList[a], EnsureList[b]]
MapThreadRagged3[func_, a_, b_] := DistributeOp[List]@func[EnsureList[a], EnsureList[b]]
Output:
MapThreadRagged1[f, {a, b}, {c, d}]
MapThreadRagged1[f, a, b]
MapThreadRagged2[f, {a, b}, {c, d}]
MapThreadRagged2[f, a, b]
MapThreadRagged3[f, {a, b}, {c, d}]
MapThreadRagged3[f, a, b]
{{f[a, c], f[a, d]}, {f[b, c], f[b, d]}}
{{f[a, b]}}
{{f[a, c], f[a, d]}, {f[b, c], f[b, d]}}
{{f[a, b]}}
{f[a, c], f[a, d], f[b, c], f[b, d]}
{f[a, b]}